2012-06-26 4 views
2

Я просто интересно, что результат будет, если я подклассы класс, который расширяет Thread и я написал следующий код и испытания:наиважнейшая запуска() в подклассе Thread

class A extends Thread { 
    public A() { 
     this.start(); 
    } 
    public void run() { 
     System.out.println(" in A " + Thread.currentThread().getName()); 
    } 
} 

class B extends A { 
    public void run() { 
     System.out.println(" in B " + Thread.currentThread().getName()); 
    } 
} 

public class OverrideRun { 
    public static void main(String[] args) { 
     A a = new A(); 
     B b = new B(); 
    }  
} 

И результат:

в нить-0
в B Thread-1

Но я не понимаю, почему две нити s создаются?

ответ

3

Это потому, что оператор B b = new B(); не вызывает параметр аргумента класса B и не вызывает конструктор параметров аргумента (по умолчанию) класса A.

Это связано с цепью конструктора.

2

Это потому, что вы создали две нити (два объекта, унаследованных от Thread), здесь:

public static void main(String[] args) { 
    A a = new A(); // #1 
    B b = new B(); // #2 
} 
2

, но я не понимаю, почему две нити созданы?

Два потока запускаются, потому что вы начинаете их в A() конструктору:

public A() { 
    this.start(); 
} 

и вы строительство двух объектов - в A и B, который проходит A:

A a = new A(); 
    B b = new B(); 

По умолчанию, когда вы говорите new B(), поскольку он не имеет конструктора no-arg, он вызывается конструктором no-arg supe rclass. Поэтому он вызовет конструктор A, который запускает поток. См. Java documentation here. Цитирование:

Вам не нужно предоставлять конструкторы для вашего класса, но при этом вы должны быть осторожны. Компилятор автоматически предоставляет конструктор по умолчанию без аргументов для любого класса без конструкторов. Этот конструктор по умолчанию вызовет конструктор без аргументов суперкласса. В этой ситуации компилятор будет жаловаться, если суперкласс не имеет конструктора без аргументов, поэтому вы должны убедиться, что он это делает. Если у вашего класса нет явного суперкласса, то он имеет неявный суперкласс Object, у которого нет конструктора без аргументов.

В стороне, это не хорошая практика, чтобы начать поток внутри его конструктора. Есть некоторые условия гонки нитей, которые могут произойти, когда вы это делаете. Гораздо лучше позвонить по телефону a.start() после того, как вы позвоните по телефону new A(). Кроме того, это лучший шаблон для определения класса, который реализует Runnable вместо расширения Thread.Так что ваш код должен быть:

class A implements Runnable() { 
    public A() { 
     // don't start it here 
    } 
    public void run() { 
     ... 
    } 
} 
... 

Thread a = new Thread(new A()); 
a.start(); 
Thread b = new Thread(new B()); 
b.start(); 
2

A расширяет Thread, B расширяет A, поэтому при создании экземпляра A и экземпляр B, вы создали два экземпляра Thread.

Обратите внимание, что это обычно предпочтительно не продлить Thread, но вместо того, чтобы просто реализовать Runnable - то передать, что Runnable к Thread(Runnable) конструктора. Это становится более чистым с точки зрения дизайна - вы на самом деле не пытаетесь изменить поведение потоков, вы просто выполняете другую задачу.

(Это также, как правило, лучше использовать средства в java.util.concurrent вместо создания потоков непосредственно в первую очередь, но там мы идем ...)

1

2 нити становятся созданы, потому что вы просите для этого, запустив следующие строки:

A a = new A(); 
    B b = new B();