网络上流传的最大的一个错误结论:
Runnable更容易可以实现多个线程间的资源共享,而Thread不可以! 这是一个二笔的结论!
Thread与Runnable的实质
Thread实现了Runnable接口并进行了扩展,而Thread和Runnable的实质是实现的关系,不是同类东西,所以Runnable或Thread本身没有可比性。
那我们来看一下为什么会出现上面的二笔结论
- 首先使用Thread来模仿线程同步
//program--Thread
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
new MyThread().start();
new MyThread().start();
}
static class MyThread extends Thread{
private int ticket = 5;
public void run(){
while(true){
System.out.println("Thread ticket = " + ticket--);
if(ticket < 0){
break;
}
}
}
}
}
运行结果:
Thread ticket = 5
Thread ticket = 5
Thread ticket = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 1
Thread ticket = 0
Thread ticket = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 1
Thread ticket = 0
Process finished with exit code 0
- 其次是Runnable实现的线程同步
//program--Runnable
public class Test2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread2 mt=new MyThread2();
new Thread(mt).start();
new Thread(mt).start();
}
static class MyThread2 implements Runnable{
private int ticket = 5;
public void run(){
while(true){
System.out.println("Runnable ticket = " + ticket--);
if(ticket < 0){
break;
}
}
}
}
}
运行结果:
Runnable ticket = 5
Runnable ticket = 4
Runnable ticket = 3
Runnable ticket = 1
Runnable ticket = 0
Runnable ticket = 2
Process finished with exit code 0
- 从两次运行结果中,我们可以看到Runnable会更接近正确的答案(先不考虑线程同步问题)。所以得出了Runnable更容易可以实现多个线程间的资源共享,而Thread不可以的结论。
真的是这样的吗?我们来看一下线程的内存分析。
- 这是根据Thread实现的并发线程。
- 这是根据Runnable实现的并发线程
- 显然Thread运行结果重复是因为new了两个MyThread,导致ticket变量有两个。Runnable中两个线程都指向一个ticket变量,所以没有重复。
推翻二笔结论
public class Test3 extends Thread {
private int ticket = 10;
public void run(){
for(int i =0;i<10;i++){
synchronized (this){
if(this.ticket>0){
try {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"卖票---->"+(this.ticket--));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] arg){
Test3 t1 = new Test3();
new Thread(t1,"线程1").start();
new Thread(t1,"线程2").start();
}
}
运行结果:
线程1卖票---->10
线程1卖票---->9
线程1卖票---->8
线程1卖票---->7
线程1卖票---->6
线程1卖票---->5
线程1卖票---->4
线程1卖票---->3
线程1卖票---->2
线程1卖票---->1
Process finished with exit code 0