多线程创建过程中的两个问题的说明:
问题一:
我们不能通过直接调用run()方法的方式来启动线程
- 调用run()方法只是单单的调用了一个方法,并没有启动这个run()方法所对应的线程,我们启动线程要通过使用子类对象调用start()方法的形式来启动这个创建的线程(也就是创建的这个对象)
问题二:
当我们再启动一个线程,要解决和之前已经启动的线程一样的功能时,我们不可以通过之前已经启动的线程(也就是之前创建的多线程对象)再一次调用start()方法,这时候如果我们再一次使用这个已经启动的线程再次调用start()方法时就会抛出一个异常(IllegalThreadStateException),我们要再启动一个相同功能的线程,就要再创建一个对象来再次调用start()方法
eg:
public void Thread1 extends Thread{
public void run(){
for(int i=0;i<100;i++){
if(i%2==0){
System.out.println(getName+":"+i);
}
}
}
}
class Test{
public static void main(String [] args){
Thread1 thread1=new Thread1();
thread1.start();
/*
这里我们要进行再启动一个和之前功能一样的线程,这个时候就要再创建一个Thread1类型的对象
来让这个对象来再次调用run()方法
*/
Thread1 thread2=new Thread1();
thread2.start();
}
}
-
Thread类中有一个属性threadStutas,这个属性是用来判断某个线程是否已经开始运行,如果这个线程开始运行,那么继承下来的threadStutas属性就不等于零,如果这个线程还没有开始运行,这个时候继承的threadStutas属性就是0,如果我们这个线程已经开始运行了,也就是说我们继承的threadStutas属性这时候不等于0,并且这个我们有重新使用这个线程(子类对象)去调用start()方法,这个时候就会抛出一个异常(IllegalThreadStateException)
-
如果创建的线程我们只使用一次,那么我们就可以通过创建Thread类的匿名子类的方法来创建线程
eg:
new Thread(){
/*
这里不是创建了一个Thread类的对象,而是创建了一个Thread的一个匿名子类的对象,也就是创建了一个线程,然后通过这个对象调用了start()方法来启动了这个线程
*/
@Override
public void run(){
}
}.start();
-
当两个线程所要执行的事情不一样了,我们就要创建两个Thread类的子类,这个时候我们在这两个子类中去重写不同的run()方法,也就可以完成不一样的功能了
-
当我们要再启动一个线程去做和另一个线程一样的事时,我们只需要再以这里的"另一个线程"的模板类的为模板创建一个对象,再用这个对象去调用run()方法,也就是创建出了和上面的"另一个线程"具有一样的功能的线程了