2014-01-14 2 views
0

Я хочу, чтобы потоки выполнялись в определенном порядке. Предположим, у меня три потока: T1, T2, T2.Выполнение более двух потоков в определенном порядке

T1 печатает 0
T2 печатает 1
T3 печатает 2

Я хочу вывод в порядке , для определенного количества времени.

Если имеется две резьбы T1 и T2. Печать 0 1, 0 1 ... может быть выполнена с использованием Задача производителя-потребителя с использованием synchronization.

+2

Вы действительно попросили ответа. – Maroun

+0

Это возможно, но не особенно удобно, и причина в том, что довольно бессмысленно задавать параллельные потоки. –

+0

Да, я ищу возможность. Не для удобства. –

ответ

2

Создать класс UnitOfWork:

public class UnitOfWork implements Runnable 
{ 
    String text; 

    public UnitOfWork(String text){ 
     this.text = text; 
    } 

    public void run(){ 
     System.out.println(text); 
    } 
} 

А затем создать единую службу нитка Исполнитель:

ExecutorService executor = ExecutorService.newSingleThreadExecutor(); 

, который вы будете использовать, как это:

UnitOfWork uow0 = new UnitOfWork("0"); 
UnitOfWork uow1 = new UnitOfWork("1"); 
UnitOfWork uow2 = new UnitOfWork("2"); 

for(int i = 0; i < 5; i++){ 
    executor.submit(uow0); 
    executor.submit(uow1); 
    executor.submit(uow2); 
} 

Когда вы недовольны пением le thread, вы можете начать использовать службу выполнения нескольких потоков, которая будет одновременно запускать задачи.

+0

Спасибо ... Это действительно сработало. –

+1

OP, если это все, что вы просили, то вам не нужны нитки, как указано выше. 'executor.submit()' в этом случае просто вызывает 'UnitOfWork.run()'. –

+0

@MarkoTopolnik nope, SingleThreadExecutor создает новый поток, который не изменится, для выполнения всей задачи. У меня есть рабочее приложение, которое опирается на этот факт. –

1

Используя метод join() в классе потоков, вы можете достичь этого.

Метод объединения позволяет одному потоку ждать завершения другого. Если t - объект Thread, поток которого в настоящее время выполняется,

t.join();

заставляет текущий поток приостанавливать выполнение до тех пор, пока поток t не завершится. Перегрузки соединения позволяют программисту указать период ожидания. Однако, как и во время сна, соединение зависит от ОС для синхронизации, поэтому вы не должны предполагать, что соединение будет ждать столько, сколько вы укажете.

Как и сон, соединение реагирует на прерывание, выходя из InterruptedException.

+0

Пожалуйста, объясните. –

+0

Лучше объясните, что .. – Maroun

+0

look google сделал это http://docs.oracle.com/javase/tutorial/essential/concurrency/join.html – Typo

1

Используйте Thread.join, чтобы обеспечить его прекращение до начала следующей нити.

public static void main(String[] args) throws InterruptedException { 
     final Thread th1 = new Thread(new Runnable() { 
      public void run() { 
       try { 
        Thread.sleep((long) (Math.random() * 1000)); 
        System.out.println("Thread 1"); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     Thread th2 = new Thread(new Runnable() { 
      public void run() { 
       try { 
        Thread.sleep((long) (Math.random() * 1000)); 
        System.out.println("Thread 2"); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     Thread th3 = new Thread(new Runnable() { 
      public void run() { 
       try { 
        Thread.sleep((long) (Math.random() * 1000)); 
        System.out.println("Thread 3"); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     th1.start(); 
     th1.join(); 
     th2.start(); 
     th2.join(); 
     th3.start(); 
    } 
+0

Я хочу, чтобы результат повторялся в течение определенного времени. Он выводит только один раз. –

+0

Затем окружает последние 5 строк циклом – PKopachevsky

+0

Это не сработает, это вызовет 'IllegalThreadStateException'. Как только поток прекращается, его нельзя запустить снова. –

0

Это минималистский кусок кода, который делает буквально что вы просили. Он полагается на механизм wait-notify.

Я согласен с тем, что вам не нужны нитки, отвечающие вашим требованиям. Простой цикл, который печатает 0-1-2, - это все, что вам действительно нужно.

import static java.lang.Thread.currentThread; 

public class A { 
    static int coordinator, timesPrinted; 
    static final int numThreads = 3, timesToPrint = 300; 
    public static void main(String[] args) { 
    for (int i = 0; i < numThreads; i++) { 
     final int myId = i; 
     new Thread(new Runnable() { public void run() { 
     while (true) synchronized (A.class) { 
      if (coordinator%numThreads == myId) { 
      System.out.println(myId+1); 
      coordinator++; 
      if (timesPrinted++ > timesToPrint) currentThread().interrupt(); 
      A.class.notifyAll(); 
      } 
      try {A.class.wait();} catch (InterruptedException e) {break;} 
     } 
     }}).start(); 
    } 
    } 
} 
+0

Спасибо @ Марко Топольник за ваш ответ. Это было не просто печать номера. Попытайтесь увидеть вопрос в разных перспективах. Просто для сценария это похоже на то, что один поток будет входным для следующего потока. –

+0

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

Смежные вопросы