前言
最近在学习多线程的Runnable和Thread,对二者的区别感到有一些疑惑。
于是乎看到了一篇博主写的文章《彻底理解Runnable和Thread的区别》https://blog.csdn.net/zhaojianting/article/details/97664370。
对他所得出的”Thread能够实现多线程之间的共享”这个结论进行反驳。
文章内容
这位博主是这么说的:
在实际工作中,我们很可能习惯性地选择Runnable或Thread之一直接使用,根本没在意二者的区别,但在面试中很多自以为是的菜货面试官会经常而且非常严肃的问出:请你解释下Runnable或Thread的区别?尤其是新手就容易上当,不知如何回答,就胡乱编一通。鄙人今天告诉你们这二者本身就没有本质区别,就是接口和类的区别。问出这个问题的面试官本身就是个二流子!如果非要说区别,请看如下:
Runnable的实现方式是实现其接口即可
Thread的实现方式是继承其类
Runnable接口支持多继承,但基本上用不到
Thread实现了Runnable接口并进行了扩展,而Thread和Runnable的实质是实现的关系,不是同类东西,所以Runnable或Thread本身没有可比性。
网络上流传的最大的一个错误结论:Runnable更容易可以实现多个线程间的资源共享,而Thread不可以! 这是一个二笔的结论!网络得出此结论的例子如下:
代码如下(示例):
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();
}
}
这位博主所说的看上去似乎没错,Thread确实也实现了多个线程之间的共享。
问题分析
但是我还是认为有问题,于是又看到一篇博客https://blog.csdn.net/u013755987/article/details/51855098
(前面这位满嘴脏话的博主居然是抄的这位博主的,代码都没改。。如此急功近利可真够可笑的)
文章的评论中有一位大佬完美的解释了我的疑惑:
大蟒蛇来了:
共用同一个对象的资源可以达到资源共享! 你的两个例子的实际线程对象都是Thread实例,然后分别将TicketThread对象和TicketRunnable对象作为target交给Thread,然后Thread执行的都是其target的run()方法,所以都实现了共享资源。 其实别人的说法也没有错可能是你理解错了吧。既然是继承,在创建多个线程的时候为何不是创建多个子类呢,子类有start()方法啊,你为何还要把子类作为一个target交给父类然后创建多个父类对象呢?你这是在反驳别人的观点时候故意这么做的吧?!
总结
Thread是由Runnable接口实现的。
Thread确实是不能实现多线程之间的资源共享,上面贴的代码中的Thread执行的只是目标对象的run()方法**(是t1,不是t1左边的Thread)**。换句话说和使用Runnable实现资源共享是差不多的,而且还失去了Runnable具有的避免单继承的优点。
希望大家不要被误导了哈