多线程(一)——Thread与Runnable
在JAVA中实现多线程的操作有两种方法,一种是继承Thread类,另外一种是实现Runnable接口。
通过Thread类和Runnable接口都可以实现多线程,那么两者之间又有那些区别与联系呢?首先我们看一下Thread的定义:
Public class Thread implements Runnable
有没有发现什么呢?哈哈,原来Thread类也是实现Runnable接口,既然如此,那这和Runnable接口的实现类有什么区别呢?
我们先看一下Thread类中的run()方法,源码如下:
public void run() {
if (target != null) {
target.run();
}
}
而target是Runnable的对象,所以,通过上面的代码我们会发现,在Thread类中的run()方法调用的是Runnable接口中的run()方法,所以如果要通过继承Thread类来实现多线程,就需要重写run()方法。
同时,我们都知道启动一个线程要通过start()方法来实现,但是Runnable接口中并没有start()方法,所以Runnable接口的实现类的启动还是要依靠Thread类来完成.
下列中,WThread是Runnable接口的子类:
WThread wt=new WThread();
Thread t=new Thread(wt);
t.start();
由上面的分析我们可以知道,Thread类和Runnable接口是相互依靠,彼此相联系的。
而它们最主要的区别在于如果一个类继承Thread类,则不适合于多个线程共享一个资源(当然你也可以用线程同步来解决,呵呵......),而实现了Runnable接口可以很好地解决这一问题。我们假设一个卖票的情景,共有10张票,然后启动四个线程去买票。
通过继承Thread类实现,代码如下:
public class WThread extends Thread{
int ticket=3;
public static void main(String []args){
for(int i=0;i<3;i++){
WThread wt=new WThread();
wt.start();
}
}
public void run(){
while(true){
if(ticket>0){
System.out.println("线程"+Thread.currentThread().getName()+"没买票之前还有余票:ticket"+ticket--+"张");
}
}
}
}
程序执行结果如下:
而通过实现Runnable接口来完成此功能,代码实现如下:
public class fWThread implements Runnable{
int ticket=3;
public static void main(String []args){
WThread wt=new WThread();
for(int i=0;i<3;i++){
new Thread(wt).start();
}
}
public void run(){
while(true){
if(ticket>0){
System.out.println("线程"+Thread.currentThread().getName()+"没买票之前还有余票:ticket"+ticket--+"张"); }
}
}
}
程序结果运行如下:
从以上两个程序的运行结果我们可以清楚的发现,同Thread类实现多线程并没有达到我们想要的结果,它不是总共有3张票,而是每个线程各自拥有3张票;而通过继承Runnable接口实现的多线程,三个线程一共才拥有3张票,即票是几个线程对象所共享的。可见实现Runnable接口相对于继承Thread类来说,更适合于多个线程去访问或操纵同一资源的情况,当然通过线程同步用Thread类也可以实现上述功能啦!!!!