2015-01-14 2 views
1

Для нижеприведенной программы при запуске и отладке на eclipse приходят разные выходы.Выполнение метода Thread run(), отличное от Run и Debug в eclipse

public class MyClass implements Runnable { 
     public static void main (String[] args) throws Exception { 
      Thread t = new Thread(new MyClass()); 
      t.start(); 
      System.out.print("Started"); 
      t.join(); 
      System.out.print("Complete"); 
     } 
     public void run() { 
      for (int i = 0; i < 4; i++) { 
       System.out.print(i); 
      } 
     } 
} 

При выполнении этого в качестве приложения Java ВЫХОД является

Started0123Complete

При проверке в отладки Режим ВЫХОД является

0123StartedComplete

Может кто-нибудь помочь в этом? это из-за двух потоков? main thread и поток, который начинается с t.start(). Если да, то почему выполнение основного потока занимает больше приоритета для завершения в первую очередь?

Благодаря

+1

Нет никакой гарантии, как это будет работать в режиме отладки/обычного режима. Если вы запускаете его несколько раз в каждом режиме, вы увидите разные выходы. – Kon

+1

Я буквально пробовал в 5,6 раз такой же выход. – NeverGiveUp161

+1

5 или 6 раз ничего, запустите это в цикле, который выполняет 1000 + раз, вы в конце концов увидите другой вывод – chancea

ответ

6

Порядок, в котором строка «Начало» и целые числа печатаются не определено по определению. После того, как вы позвоните start, нет гарантии, что код в методе run будет выполнен до или после любого другого оператора, который появляется перед вызовом join. Это характер многопоточных приложений.

Тот факт, что вы видите определенный выход в режиме отладки или в режиме запуска, вероятно, является случайным и может измениться, если вы запускаете свой код много раз или на разных платформах/версиях JVM. Если вам нужен детерминированный порядок в этом случае, единственный способ добиться этого - напечатать строку до, вызвав start или ввести другой вид семафора, чтобы заставить поток ждать основного потока или наоборот.

+1

На самом деле, это не единственное/возможное/способ, которым вы можете его достичь, какой-то общий мьютекс между дочерним и родительским потоками также позволит вам это сделать, например. Семафор – tddmonkey

+0

@MrВигглы касаются, меняют мой ответ! –

2

Это совпадение. Вы не можете управлять планировщиком потоков.

Однако в среде отладки debugger подключается к вашему коду для проверки значений и выполнения. Эта проверка увеличивает объем работы, выполняемой на срез времени потока.

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

0

Да, из-за 2 потоков Но выход непредсказуем. Нет, основной поток не получает высокого приоритета, потому что его MAIN. вы не можете сказать какое-либо конкретное чередование выполнения в многопоточных.

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

+0

Это может быть так: есть ли какая-либо статья, которая поможет вам лучше понять это? если это действительно происходит так, как вы сказали. – NeverGiveUp161

1

Это не связано с тем, что он находится в режиме отладки или нет. Там нет никакой гарантии того, когда это запускается на выполнение

System.out.print("Started"); //this is in the main thread 

по сравнению с

for (int i = 0; i < 4; i++) { // this is in the started thread 
      System.out.print(i); 
     } 

Это может быть даже

01Started23Complete 
+0

Мне нравится, что вы показали возможность остановки петли на полпути. – chancea

-1

В обоих (Run/Debug) режим вывода будет

Начато0123Сообщество

Вы видите результат 0123StartedComplete, потому что у вас должна быть точка отладки внутри основного кода потока, вот почему.

Если вы хотите лучше понять, а затем переместите метод run() в MyClass и установите точку отладки внутри метода запуска, вы увидите, что она печатается как Started0123Complete.

Внутренняя ссылка, основная тема создает субтитр «t», и когда вызывается t.start(), он ждет, чтобы захватить монитор для выполнения потока (т.е. run()) и когда вы добавляете инструкцию debug в основной поток , под-поток входит в монитор и запускает метод, и после его завершения основной поток снова запускается.

+0

No – chancea

+0

Этот парень на самом деле прав ... Метод run уже находится в классе. Я просто меняю точку отладки на запуск, но я хочу понять, что происходит внутренне – NeverGiveUp161

+1

Внутренняя ссылка, основная тема создает subthread «t», и когда вызывается t.start(), он ожидает захвата монитора для выполнения потока (т.е. run()) и когда вы добавляете инструкцию отладки в основной поток, -thread вводит в монитор и запускает метод, и после его завершения основной поток снова запускается. –

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