通过继承Thread类与实现Runnable接口实现多线程以及两者的区别
实现多线程代码有两种方式:一种是继承Thread类;另一种是实现Runnable接口(JDK1.5之后有新的接口Callable)
继承Thread类
Thread子类中必须明确地覆写Thread类中地run()方法,此方法是线程的主体。
正确地启动线程是不能直接调用run()方法的,而是应该调用Thread类中继承而来的start()方法。
要注意的是一个类通过继承Thread类来实现,则一个对象只能调用一次start()方法,如果多次调用,则会抛出"IllegalThreadStateException"异常。
实现Runnable接口
接口定义:
public interface Runnable{
public void run();
}
在Runnable接口中只提供有一个抽象方法run(),因此要启动多线程还是要依靠Thread类完成启动。
Thread类中提供了 public Thread(Runnable target)和 public Thread(Runnable target,String name)两个构造方法接收Runnable的子类实例对象。
两者的区别
Thread类和Runnable接口的联系
public class Thread extends Object implements Runnable
Thread类的部分定义的代码:
private Runnable target;
public Thread(Runnable target,String name){
init(null,target,name,0);
}
private void init(ThreadGroup g,Runnable target,String name,long stackSize){
...
this.target=target;
...
}
public void run(){
if(target!=null){
target.run();
}
}
从定义中可以发现,Thread类中的run方法调用的是Runnable接口中的run()方法,也就是说,此方法是由Runnable子类完成的。所以通过继承Thread类实现多线程,则必须覆写run()方法。
两者使用上的区别
如果一个类继承Thread类,则不适合与多个线程共享资源,而实现了Runnable接口,就可以方便地实现资源共享。
例1、继承Thread类不能资源共享
class MyThread extends Thread{
private int ticket=5;
public void run(){
for(int i=0;i<100;i++){
if(ticket>0){
System.out.println("卖票:ticket="+ticket--);
}
}
}
}
public class Demo{
public static void main(String[] args){
MyThread mt1=new MyThread();
MyThread mt2=new MyThread();
MyThread mt3=new MyThread();
mt1.start(); //启动第一个线程
mt2.start(); //启动第一个线程
mt3.start(); //启动第一个线程
}
}
可能的程序结果:
卖票:ticket=5
卖票:ticket=4
卖票:ticket=3
卖票:ticket=2
卖票:ticket=1
卖票:ticket=5
卖票:ticket=4
卖票:ticket=3
卖票:ticket=2
卖票:ticket=1
卖票:ticket=5
卖票:ticket=4
卖票:ticket=3
..........
例2、实现Runnable接口可以资源共享
class MyThread implements Runnable{
private ticket=5;
public void run(){
for(int i=0;i<100;i++){
if(ticket>0){
System.out.println("卖票:ticket="+ticket--);
}
}
}
}
public class Demo{
public static void main(String[] args){
MyThread mt=new MyThread();
/*启动3个线程*/
new Thread(mt).start();
new Thread(mt).start();
new Thread(mt).start();
}
}
程序运行结果:
卖票:ticket=5
卖票:ticket=4
卖票:ticket=3
卖票:ticket=2
卖票:ticket=1
Runnable接口相较Thread类下的优点
(1)适合多个相同程序代码的线程处理同一资源的情况。
(2)可以避免由于Java的单继承特性所带来的局限。
(3)增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。
ket=1
### Runnable接口相较Thread类下的优点
(1)适合多个相同程序代码的线程处理同一资源的情况。
(2)可以避免由于Java的单继承特性所带来的局限。
(3)增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。