2015-04-01 3 views
1

Я хочу напечатать серию из 1 до 100 чисел, используя n количество потоков (позволяет взять 10 потоков для этого). Условие 1-й нити будет иметь порядковый номер от 1, 11,21 .... 91, вторая нить будет иметь последовательность 2,12,22 ..... 92 и так далее. Все остальные потоки будут иметь порядковый номер, подобный этому. Теперь я хочу напечатать номер в последовательности от 1 до 100. Я знаю, что мы можем использовать синхронизацию, ждать и уведомлять метод и использовать счетчик переменных или флагов, но я не думаю, что это хорошая идея его использовать. Я хочу использовать без параллелизма (например, исполнители и т. Д.), Как я это сделаю. Пожалуйста, предложите.Последовательность с использованием потока Синхронизация

public class PrintNumberSequenceUsingRunnable { 
    int notifyValue = 1; 

    public static void main(String[] args) { 
     PrintNumberSequenceUsingRunnable sequence = new PrintNumberSequenceUsingRunnable(); 
     Thread f = new Thread(new First(sequence), "Fisrt"); 
     Thread s = new Thread(new Second(sequence), "Second"); 
     Thread t = new Thread(new Third(sequence), "Third"); 
     f.start(); 
     s.start(); 
     t.start(); 
    } 
} 

class First implements Runnable { 
    PrintNumberSequenceUsingRunnable sequence; 

    public First(PrintNumberSequenceUsingRunnable sequence) { 
     this.sequence = sequence; 
    } 

    @Override 
    public void run() { 
     printFist(); 
    } 

    private void printFist() { 
     synchronized (sequence) { 
      for (int i = 1; i <= 20; i += 3) { 
       while (sequence.notifyValue != 1) { 
        try { 
         sequence.wait(); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
       System.out.println(Thread.currentThread().getName() + " " + i); 
       sequence.notifyValue = 2; 
       sequence.notifyAll(); 
      } 
     } 
    } 
} 

class Second implements Runnable { 
    PrintNumberSequenceUsingRunnable sequence; 

    public Second(PrintNumberSequenceUsingRunnable sequence) { 
     this.sequence = sequence; 
    } 

    @Override 
    public void run() { 
     printSecond(); 
    } 

    private void printSecond() { 
     synchronized (sequence) { 
      for (int i = 2; i <= 20; i += 3) { 
       while (sequence.notifyValue != 2) { 
        try { 
         sequence.wait(); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
       System.out.println(Thread.currentThread().getName() + " " + i); 
       sequence.notifyValue = 3; 
       sequence.notifyAll(); 
      } 
     } 
    } 

} 

class Third implements Runnable { 
    PrintNumberSequenceUsingRunnable sequence; 

    public Third(PrintNumberSequenceUsingRunnable sequence) { 
     this.sequence = sequence; 
    } 

    @Override 
    public void run() { 
     printThrid(); 
    } 

    private void printThrid() { 
     synchronized (sequence) { 
      for (int i = 3; i <= 20; i += 3) { 
       while (sequence.notifyValue != 3) { 
        try { 
         sequence.wait(); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
       System.out.println(Thread.currentThread().getName() + " " + i); 
       sequence.notifyValue = 1; 
       sequence.notifyAll(); 
      } 
     } 
    } 
} 
+0

В качестве упражнения ваша проблема определенно интересна. Но я надеюсь, вы поймете, что то, что вы хотите сделать, - это сериализовать все исполнение и привести его в порядок, что приведет к поражению цели многопоточности. – Guillaume

+0

Вы опубликовали код, который, на первый взгляд, кажется, делает то, что вы описываете; поэтому я действительно не понимаю, каков ваш вопрос. У вас есть ошибка компиляции или какая-то ошибка? – ruakh

+0

Кстати, вам не нужны три отдельных класса для ваших трех потоков. – ruakh

ответ

1

Нужно иметь значения, отсортированные по каждому потоку. Каждый раз, когда поток записывает число, он запускает событие в шине событий. Все темы подписаны на мероприятие.

Вы запускаете систему путем запуска события [минимальное значение - 1].

Каждый поток получит уведомление о публикации значения [минимальное значение - 1]. Будет действовать только поток, который имеет значение [минимальное значение] и инициирует новое событие для значения [минимальное значение + 1].

Редактировать: Я не тестировал его, но что-то вроде этого.

static void main(String[] args) { 
    List<Deque<Integer>> publishQueues = new ArrayList<>(); 
    for (int i = 1; i <= 10; i++) { 
     new Thread(new Worker(i, publishQueues)).start(); 
    } 
} 

class Worker implements Runnable { 
    Deque subscriberQueue; 
    List<Deque<Integer>> publishQueues; 
    int i; 
    Worker(int i, List<Deque<Integer>> publishQueues) { 
     this.i = i; 
     this.publishQueues = publishQueues; 
     this.subscriberQueue = new ConcurrentLinkedDeque<>(); 
     this.publishQueues.add(this.subscriberQueue); 
    } 

    void Run() { 
     LinkedList<Integer> ints = new LinkedList<>(); 
     for (int j = i; j <= 100; j+=10) { 
      ints.add(j); 
     } 

     while (true) { 
      Integer publishedInteger = subscriberQueue.poll(); 
      if (publishedInteger == ints.getFirst() - 1) { 
       Integer integer = ints.poll(); 
       System.out.println(integer); 
       for (Dequeu<Integer> publishQueue : publishQueues) { 
        publishQueue.addLast(integer); 
       } 
      } 
     } 
    } 
}