首先,从使用形式上,使用Runnable实现多线程更好,因为避免了单继承问题,但除了这一点之外,Thread和Runnable之间也存在一些联系。观察Thread类的定义形式:
public class Threadextends Objectimplements Runnable
原来Thread类是Runnable接口的子类,那么Thread类也应该覆写了run()方法。
@Override public void run() { if (target != null) { target.run(); } }
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
private void init有this.target = target;
而之前target的定义是: private Runnable target;
可以形成如下的类继承结构:
所以,在多线程的处理上使用的是代理设计模式。除了上面的关系,在实际开发中使用Runnable还有一个特点:使用Runnable实现的多线程的程序类可以更好的描述出数据共享的概念(并不是说Thread不能)。
(目标是产生若干个线程进行同一数据的处理操作)
范例:使用Thread实现数据操作
class MyThread extends Thread{ //是一个线程的主体类 private int ticket=10;//一共10张票 @Override public void run() { for(int x=0;x<20;x++){ if(this.ticket>0){ System.out.println("卖票,ticket="+this.ticket--); } } } } public class ThreadTest { public static void main(String[] args) { new MyThread().start(); new MyThread().start(); new MyThread().start(); } }
此时只是想启动三个线程进行卖票处理。结果变为了各自卖各自的三张票。没有实现共享。分析内存关系:是各自自己的
改为:
class MyThread extends Thread{ //是一个线程的主体类 private int ticket=10;//一共10张票 @Override public void run() { for(int x=0;x<20;x++){ if(this.ticket>0){ System.out.println("卖票,ticket="+this.ticket--); } } } } public class ThreadTest { public static void main(String[] args) { MyThread mt=new MyThread(); new Thread(mt).start(); new Thread(mt).start(); new Thread(mt).start(); //即new Thread(new MyThread()).start(); } }
输出结果是:只有10张票,是实现了数据共享。但是相当有两个人都有水,但是这个人非要喝另外一个人的水,并不好。
范例:使用Runnable实现共享
class MyThread implements Runnable{ //是一个线程的主体类 private int ticket=10;//一共10张票 @Override public void run() { for(int x=0;x<20;x++){ if(this.ticket>0){ System.out.println("卖票,ticket="+this.ticket--); } } } } public class ThreadTest { public static void main(String[] args) { MyThread mt=new MyThread(); new Thread(mt).start(); new Thread(mt).start(); new Thread(mt).start(); } }
这时的MyThread是没有start方法的,所以是可以使用Thread的start方法的。实现了数据共享。输出结果也是共同卖10张票。
Runnable能比Thread更好的实现数据共享的功能,但不是能不能的区别。又因为Runnable用的多,所以就能实现好的实现数据共享的。
时间: 2024-10-12 23:54:47