概述
Runnable 是接口。
Thread 是类,且实现了Runnable接口。
Thread部分源码
public classThreadimplementsRunnable
{private static classCaches
{static final ConcurrentMap subclassAudits = newConcurrentHashMap();static final ReferenceQueue subclassAuditsQueue = new ReferenceQueue();
在使用Runnable定义的子类中没有start()方法,只有Thread类中才有。
1 public interfaceRunnable2 {3
4 public abstract voidrun();5 }
Thread类,有一个构造方法:public Thread(Runnable targer)
1 publicThread(Runnable runnable)2 {3 daemon = false;4 stillborn = false;5 threadLocals = null;6 inheritableThreadLocals = null;7 threadStatus = 0;8 blockerLock = newObject();9 init(null, runnable, (new StringBuilder()).append("Thread-").append(nextThreadNum()).toString(), 0L);10 }
此构造方法接受Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程。
使用情况
在程序开发中只要是多线程肯定永远以实现Runnable接口为主。
实现Runnable接口相比继承Thread类有如下好处:1、避免继承的局限,一个类可以继承多个接口。2、适合于资源的共享。
实例
以卖票为例,总共只有10张动车票了,全国3个窗口在卖。
继承Thread类的方法
1 packagemultithreading;2
3 public class MyThreadWithExtends extendsThread {4
5 private int tickets = 10;6
7 @Override8 public voidrun() {9
10 for (int i = 0; i <= 100; i++) {11 if(tickets>0){12 System.out.println(Thread.currentThread().getName()+"--卖出票:" + tickets--);13 }14 }15 }16
17
18 public static voidmain(String[] args) {19 MyThreadWithExtends thread1 = newMyThreadWithExtends();20 MyThreadWithExtends thread2 = newMyThreadWithExtends();21 MyThreadWithExtends thread3 = newMyThreadWithExtends();22
23 thread1.start();24 thread2.start();25 thread3.start();26
27 //每个线程都独立,不共享资源,每个线程都卖出了10张票,总共卖出了30张。如果真卖票,就有问题了。
28 }29
30 }
运行结果:
Thread-0--卖出票:10
Thread-2--卖出票:10
Thread-1--卖出票:10
Thread-2--卖出票:9
Thread-0--卖出票:9
Thread-2--卖出票:8
Thread-1--卖出票:9
Thread-2--卖出票:7
Thread-0--卖出票:8
Thread-2--卖出票:6
Thread-2--卖出票:5
Thread-2--卖出票:4
Thread-1--卖出票:8
Thread-2--卖出票:3
Thread-0--卖出票:7
Thread-2--卖出票:2
Thread-2--卖出票:1
Thread-1--卖出票:7
Thread-0--卖出票:6
Thread-1--卖出票:6
Thread-0--卖出票:5
Thread-0--卖出票:4
Thread-1--卖出票:5
Thread-0--卖出票:3
Thread-1--卖出票:4
Thread-1--卖出票:3
Thread-1--卖出票:2
Thread-0--卖出票:2
Thread-1--卖出票:1
Thread-0--卖出票:1
每个线程都独立,不共享资源,每个线程都卖出了10张票,总共卖出了30张。如果真卖票,就有问题了。
实现Runnable接口方式
1 packagemultithreading;2
3 public class MyThreadWithImplements implementsRunnable {4
5 private int tickets = 10;6
7 @Override8 public voidrun() {9
10 for (int i = 0; i <= 100; i++) {11 if(tickets>0){12 System.out.println(Thread.currentThread().getName()+"--卖出票:" + tickets--);13 }14 }15 }16
17
18 public static voidmain(String[] args) {19 MyThreadWithImplements myRunnable = newMyThreadWithImplements();20 Thread thread1 = new Thread(myRunnable, "窗口一");21 Thread thread2 = new Thread(myRunnable, "窗口二");22 Thread thread3 = new Thread(myRunnable, "窗口三");23
24 thread1.start();25 thread2.start();26 thread3.start();27 }28
29 }
运行结果:
窗口二--卖出票:10窗口三--卖出票:9窗口一--卖出票:8窗口三--卖出票:6窗口三--卖出票:4窗口三--卖出票:3窗口三--卖出票:2窗口三--卖出票:1窗口二--卖出票:7窗口一--卖出票:5
每个线程共享了对象myRunnable的资源,卖出的总票数是对的,但是顺序是乱的,怎么办?