对于线程的创建及更加详细的信息可以参看博客《JAVA--线程》,下面是对线程创建的细化及简单再实现。
在java中如果要创建线程的话,一般有两种方式:1)继承Thread类;2)实现Runnable接口。
方式一:继承Thread类
MyThread:
package com.tgb.hjy;
public class MyThread extends Thread{
private String name;
public MyThread(String name){
this.name=name;
}
@Override
public void run(){
System.out.println("name:"+name+",子线程ID:"+Thread.currentThread().getId());
}
}
ClientThread:
package com.tgb.hjy;
public class ClientThread{
public static void main(String[] args){
System.out.println("主线程ID:"+Thread.currentThread().getId());
MyThread thread1=new MyThread("thread1");
thread1.start();
}
}
方式二:实现Runnable接口
MyRunnable:
package com.tgb.hjy;
public class MyRunnable implements Runnable{
public MyRunnable(){
}
@Override
public void run() {
System.out.println("主线程ID:"+Thread.currentThread().getId());
}
}
ClientRunnable:
package com.tgb.hjy;
public class ClientRunnable {
public static void main(String[] args){
System.out.println("子线程ID:"+ Thread.currentThread().getId());
MyRunnable myRunnable=new MyRunnable();
Thread thread=new Thread(myRunnable);
thread.start();
}
}
注意,这种方式必须将Runnable作为Thread类的参数,然后通过Thread的start方法来创建一个新线程来执行该子任务。如果直接调用Runnable的run方法的话,是不会创建新线程的,这根普通的方法调用没有任何区别。
事实上,查看Thread类的实现源代码会发现Thread类是实现了Runnable接口的。
上面我们一直在说,如果调用run方法,即相当于在主线程中执行run方法,跟普通的方法调用没有任何区别,此时并不会创建一个新的线程来执行定义的任务。
下面我们来验证一下:
public static void main(String[] args){
System.out.println("主线程ID:"+Thread.currentThread().getId());
MyThread thread1=new MyThread("thread1");
thread1.start();
MyThread thread2=new MyThread("thread2");
thread2.run();
}
调用thread2.start();方法输出结果为:
从输出结果可以得出以下结论:
1)thread1和thread2的线程ID不同,thread2和主线程ID相同,说明通过run方法调用并不会创建新的线程,而是在主线程中直接运行run方法,跟普通的方法调用没有任何区别;
2)虽然thread1的start方法调用在thread2的run方法前面调用,但是先输出的是thread2的run方法调用的相关信息,说明新线程创建的过程不会阻塞主线程的后续执行。
总结:
在Java中,类仅支持单继承,也就是说,当定义一个新的类的时候,它只能扩展一个外部类.这样,如果创建自定义线程类的时候是通过扩展Thread类的方法来实现的,那么这个自定义类就不能再去扩展其他的类,也就无法实现更加复杂的功能。因此,如果自定义类必须扩展其他的类,那么就可以使用实现Runnable接口的方法来定义该类为线程类,这样就可以避免Java单继承所带来的局限性。
还有一点最重要的就是使用实现Runnable接口的方式创建的线程可以处理同一资源,从而实现资源的共享.--具体内容参看博客《JAVA--线程》