Нечеткое выполнение небольшой программы с потоками

Я создал тестовую программу, использующую потоки:

class First implements Runnable {
 public void run() {
 System.out.print("One ");
 }
}

class Second implements Runnable {
 Thread other;
 Second(Thread t) {other = t;}
 public void run() {
 System.out.print("Two");
 }
}

public class ThreadTest {
 void go() {
 First first = new First();
 Thread t = new Thread(first);
 Second second = new Second(t);
 Thread u = new Thread(second);
 t.start();
 u.start();
 }

 public static void main(String[] args) {
 new ThreadTest().go();
 }
}

Я ожидал, что он напечатает:

Один один

Но это внезапно для меня напечатало:

Один два

Я не понимаю, почему это происходит. Я думал, что в обоих потоках должен быть вызван метод run() из первого класса. Потому что я передал первый экземпляр в конструктор Thread и передал этот созданный поток во второй конструктор. Таким образом, метод run() из первого класса имеет приоритет над методом run() из второго класса. Где я ошибаюсь?

2 ответа

Нет причин, по которым второй поток должен печатать "One". Он может иметь ссылку на первый Thread, но он ничего не делает с ним. Ничто не отменяет метод Second run, поэтому он просто печатает Two.

Чтобы сделать второй Thread Print One, run вызов другого метода run Thread.

class Second implements Runnable {
 Thread other;
 Second(Thread t) {other = t;}
 public void run() {
 other.run();
 }
}

Но это необычно назвать один Thread run метод из run метода другого Thread. На самом деле, это необычно, чтобы вызвать run прямо на всех.


Я ожидал, что он напечатает: One One. Но это внезапно для меня напечатало: One Two

Вы начинаете 2 потока. Метод First.run() выводит "Один". Метод Second.run() выдает "Два". Просто потому, что вы назначаете other = t; во Second конструкторе не изменяется его метод run().

Потому что я передал первый экземпляр в конструктор Thread и передал этот созданный поток во второй конструктор. Таким образом, метод run() из первого класса имеет приоритет над методом run() из второго класса. Где я ошибаюсь

Возможно, в Second.run() вы намеревались вызвать other.run() или что-то еще? Это было бы странно, но это не рекомендуется. Вы не должны связывать такие классы Thread. Вероятно, вы должны пройти в First методе, а затем выполните:

class Second implements Runnable {
 First first;
 Second(First first) { this.first = first; }
 public void run() {
 first.run();
 }
}

Но даже тогда, это немного странный шаблон, чтобы вызвать один метод run() от другого.

licensed under cc by-sa 3.0 with attribution.