2013-08-07 3 views
2

Я изучал метод Thread join(), и я наткнулся на ThreadJoinMethod сообщение на stackoverflow. Я изменил код для разработки рабочего примера, и я запутался в выходе . Фрагмент кода.Thread join() method output confusion

class JoinRunnable implements Runnable{ 

    public void run() { 
    for(int i =0 ; i < 4 ; i++){ 
     System.out.println(i); 
    } 
    } 
} 
public class TestJoin{ 
    public static void main(String[] args) throws InterruptedException { 
    JoinRunnable joinRunnable = new JoinRunnable(); 
    Thread t1 = new Thread(joinRunnable); 
    Thread t2 = new Thread(joinRunnable); 
    t1.start(); 
    t2.start(); 
    System.out.println("Currently running thread: " + Thread.currentThread().getName()); 
    t1.join(); 
    t2.join(); 
    System.out.println("I must wait"); 
    } 
} 

Выход следующей программы: -

0 
1 
2 
3 
0 
1 
2 
3 
Currently running thread: main 
I must wait 

Я смущен на выходе. Текущая нить будет соединена после вызова join по t1 и t2, но почему заявление, "Currently Running Thread: main" печатает после того, как t1 и t2 завершает? У меня отсутствует какая-то важная концепция здесь? Поскольку main() присоединяется к t1 и t2 после операторов объединения не раньше. Может ли кто-нибудь это уточнить?

+0

Возможно ли, что два других потока просто закончат свои процедуры перед вызовами в различные библиотеки, задействованные в 'Thread',' System', 'out' и т. Д., Дает результат? Протестируйте, сделав вывод от 1 до 10000 для каждого из них. Затем получите удовольствие от просеивания. – christopher

+2

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

+0

отлично, я просто добавил спать сейчас. В настоящий момент напечатан текущий метод-main. Поэтому выход должен отличаться. Благодаря тонну. – benz

ответ

4

Поток начинается после того, как вы звоните start() Это означает, что он может начинаться до любой строки, которая приходит после и может даже завершить перед строками, которые появляются после него.

1

Это просто работает слишком быстро. Вставьте короткий сон в эти два потока.

2

Вы интерпретируете это неправильно. join() метод вызывает ожидание t1 и t2. Так что main не выйдет до завершения t1 и t2. И совершенно произвольно, что печатается первым, в основном в зависимости от приоритета потоков. Чтобы установить предопределенное поведение, вам необходимо синхронизировать потоки.

+0

Я думаю, что вы неправильно истолковали вопрос. –

+0

Но это вероятность того, что t1 и t2 не войдут в рабочее состояние, и этот оператор печатает «Currnetly running thread main». Это? – benz

+0

@RohitJain Читать снова, он говорит, что основной поток будет соединен (значит он будет ждать). – user2550754

1

Вот описание метода join():
Blocks the current Thread (Thread.currentThread()) until the receiver finishes its execution and dies. (от Javadoc)
В самом деле, вы можете заблокировать основной поток, который ждет t1 & t2, чтобы остановить.

+0

Но это вероятность того, что t1 и t2 не войдут в рабочее состояние, и этот оператор печатает «Currnetly running thread main». Это? – benz

+0

Я думаю, что комментарий Питера Лори более релевантен для вашей проблемы, чем мой, я думаю, вы должны добавить короткий сон (как сказано выше), чтобы проверить, закончится ли процесс t1 & t2 раньше или нет. – Sw4Tish

+0

Спасибо @ Sw4Tish. Я сделал это, и на этот раз результат был другим. – benz

2

System.out.println синхронизирован на базовом экземпляре OutputStream (по крайней мере, в реализации, которую я имею здесь, на моем ПК). Временные промежутки между каждым println очень коротки, поэтому маловероятно, что println из другого потока будет иметь шанс быть выполненным. Таким образом, похоже, что у вас есть определенный порядок на println (по крайней мере, с очень высокой вероятностью). Вставьте несколько спит и позвольте петлям подсчитать выше, и вы сможете наблюдать за другим поведением.

+0

Thankyou очень много людей. Я понял концепцию здесь. – benz

1

t1 и t2 Thread начали и закончили свою работу до Вашего заявления

System.out.println("Currently running thread: " + Thread.currentThread().getName()); 

фактически может производить любой выход на screen.So резьбы t1 и t2 были выполнил свою задачу и основной поток может двигаться дальше, как потоки, соединенные с ними, выполняются с помощью метода run().

Если вы хотите изучить и понять концепцию объединения двух потоков, просьба предоставить Thread.sleep (1000) в цикле for for в методе run.