2014-10-05 3 views
0

Я написать следующий пример:Почему не запускается вызов метода?

public class MyThread extends Thread{ 
    MyThread(Runnable r){ 
     super(r); 
    } 
    public void run(){ 
     System.out.println("run"); 
    } 
} 
public static void main(String[] args) 
{ 
    Thread t = new MyThread(new Runnable() { 
     @Override 
     public void run() { 
      System.out.println("rrrrrrrrrruuuuuuuuuuuun"); 
     } 
    }); 
    t.start(); //run 
} 

Почему работать methdo определяется в MyThread был назван вместо этого?

+0

@ practice2perfect я написал отдельный класс под названием MyThread и просто импортировать его в Main. –

+0

Почему ваш основной метод не инкапсулирован в класс? –

+2

@Fev Это всего лишь фрагмент основного класса и разделенного класса MyThread. –

ответ

3

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

Для записи, вот реализация по умолчанию Thread.run(), что вы перегрузили:

private Runnable target; 

public void run() { 
    if (target != null) { 
     target.run(); 
    } 
} 
+0

Да, это все объясняет. Спасибо. –

3

Потому что вы MyThread.run не переопределяете, но Runnable.run есть. Теперь, если вы посмотрите на свою реализацию MyThread.run, сохраненный Runnable не играет никакой роли. Другими словами, не имеет значения, какой runnable вы даете с конструктором. Вы должны использовать:

public static void main(String[] args) 
{ 
    Thread t = new MyThread() { 
     @Override 
     public void run() { 
      System.out.println("rrrrrrrrrruuuuuuuuuuuun"); 
     } 
    }); 
    t.start(); //run 
} 

Как @BorisTheSpider нот, переопределение Thread, вообще говоря, не является хорошей практикой: а Thread несет ответственность начать Thread и дать управление исполняемым. Лучше реализация будет:

public static void main(String[] args) 
{ 
    Thread t = new Thread(new MyThread() { 
     @Override 
     public void run() { 
      System.out.println("rrrrrrrrrruuuuuuuuuuuun"); 
     } 
    })); 
    t.start(); //run 
} 
+0

Лучше использовать «Runnable» для «Thread», а не для расширения «Thread». Это отделяет проблемы более чисто и позволяет избежать множества ошибок синхронизации, возникающих в результате блокировки на мониторе экземпляров потоков. –

+0

@BoristheSpider: Я согласен, но на самом деле это был не вопрос. Вопрос в том, почему принцип наследования не сработал. Но вы прокомментируете конструктивный в некотором смысле, что он показывает «хорошую практику». Я добавлю это к ответу. –

+2

@BoristheSpider: обновлено, лучше? –

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