鄙人的新书《Elasticsearch权威指南》正式出版发行,欢迎购买!本书由华为、中兴高级技术专家全面审读并撰序,助您挑战百万年薪 购书链接:

《Elasticsearch权威指南》

欢迎关注鄙人公众号,技术干货随时看!

  在实际工作中,我们很可能习惯性地选择Runnable或Thread之一直接使用,根本没在意二者的区别,但在面试中很多自以为是的菜货面试官会经常而且非常严肃的问出:请你解释下Runnable或Thread的区别?尤其是新手就容易上当,不知如何回答,就胡乱编一通。鄙人今天告诉你们这二者本身就没有本质区别,就是接口和类的区别。问出这个问题的面试官本身就是个二流子!如果非要说区别,请看如下:

  1. Runnable的实现方式是实现其接口即可
  2. Thread的实现方式是继承其类
  3. Runnable接口支持多继承,但基本上用不到
  4. Thread实现了Runnable接口并进行了扩展,而Thread和Runnable的实质是实现的关系,不是同类东西,所以Runnable或Thread本身没有可比性。

  网络上流传的最大的一个错误结论:Runnable更容易可以实现多个线程间的资源共享,而Thread不可以! 这是一个二笔的结论!网络得出此结论的例子如下:

//program--Thread
public class Test {public static void main(String[] args) {// TODO Auto-generated method stubnew 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 = 0Process finished with exit code 0

  很显然,总共5张票但卖了10张。这就像两个售票员再卖同一张票,原因稍后分析。现在看看使用runnable的结果:

//program--Runnable
public class Test2 {public static void main(String[] args) {// TODO Auto-generated method stubMyThread2 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 = 2Process finished with exit code 0

  嗯,嗯,大多数人都会认为结果正确了,而且会非常郑重的得出:Runnable更容易可以实现多个线程间的资源共享,而Thread不可以! 真的是这样吗?大错特错!
  program–Thread这个例子结果多卖一倍票的原因根本不是因为Runnable和Thread的区别,看其中的如下两行代码:

        new MyThread().start();new MyThread().start();

  例子中,创建了两个MyThread对象,每个对象都有自己的ticket成员变量,当然会多卖1倍。如果把ticket定义为static类型,就离正确结果有近了一步(因为是多线程同时访问一个变量会有同步问题,加上锁才是最终正确的代码)。
现在看program–Runnable例子中,如下代码:

        MyThread2 mt=new MyThread2();new Thread(mt).start();new Thread(mt).start();

  只创建了一个Runnable对象,肯定只卖一倍票(但也会有多线程同步问题,同样需要加锁),根本不是Runnable和Thread的区别造成的。再来看一个使用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();}}

运行结果如下:

线程1卖票---->10
线程1卖票---->9
线程1卖票---->8
线程1卖票---->7
线程1卖票---->6
线程1卖票---->5
线程1卖票---->4
线程1卖票---->3
线程1卖票---->2
线程1卖票---->1Process finished with exit code 0

  上例中只创建了一个Thread对象(子类Test3),效果和Runnable一样。synchronized这个关键字是必须的,否则会出现同步问题,篇幅太长本文不做讨论。
  上面讨论下来,Thread和Runnable没有根本的没区别,只是写法不同罢了,事实是Thread和Runnable没有本质的区别,这才是正确的结论,和自以为是的大神所说的Runnable更容易实现资源共享,没有半点关系!
  现在看下Thread源码:

public
class Thread implements Runnable {/* Make sure registerNatives is the first thing <clinit> does. */private static native void registerNatives();static {registerNatives();}private volatile String name;private int            priority;private Thread         threadQ;private long           eetop;

  可以看出,Thread实现了Runnable接口,提供了更多的可用方法和成员而已。

  结论,Thread和Runnable的实质是继承关系,没有可比性。无论使用Runnable还是Thread,都会new Thread,然后执行run方法。用法上,如果有复杂的线程操作需求,那就选择继承Thread,如果只是简单的执行一个任务,那就实现runnable。
  再遇到二笔面试官问Thread和Runnable的区别,你可以直接鄙视了!

彻底理解Runnable和Thread的区别相关推荐

  1. Android开发笔记之:Handler Runnable与Thread的区别详解

    From:http://www.jb51.net/article/37465.htm 本篇文章是对在Android中Handler Runnable与Thread的区别进行了详细的分析介绍,需要的朋友 ...

  2. 彻底理解Runnable与Thread,真的有区别吗?

    网络上流传的最大的一个错误结论: Runnable更容易可以实现多个线程间的资源共享,而Thread不可以! 这是一个二笔的结论! Thread与Runnable的实质 Thread实现了Runnab ...

  3. Java中Runnable和Thread的区别

    2019独角兽企业重金招聘Python工程师标准>>> 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.la ...

  4. Java线程之两种方法Runnable和Thread的区别

    在java中有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口: 1>Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的 ...

  5. java中runnable_Java中Runnable和Thread的区别

    在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...

  6. Runnable和Thread的区别

    1.Runnable的实现方式是实现其接口即可 2.Thread的实现方式是继承其类 3.Runnable接口支持多继承,但基本上用不到 4.Thread实现了Runnable接口并进行了扩展,而Th ...

  7. 【转】java线程系列---Runnable和Thread的区别

    在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...

  8. 再谈 Java中Runnable和Thread的区别

    在面试中老有面试官问这个问题,个人觉得这个问题问的没有技术,一个死记硬背就能回答的很好.但是更深的回答是什么了,那就是直接回答源码吧. thread类实现了runnable 接口 ,Runnable就 ...

  9. Java多线程中的Runnable和Thread

    摘要: 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的r ...

最新文章

  1. 简单分析一下socket中的bind
  2. 隔板都被拉去做核酸了?
  3. 废旧光盘手工小制作_佳味家味浓 丨佳人美食手工零食课堂:咸蛋黄牛轧糖夹心小饼干制作活动...
  4. 比特币早期投资家:没有人能够阻止其发展 TechWeb 09-27 09:10 凤凰科技讯 据CNBC网站北京时间9月27日报道,风险投资家、“Social+Capital”基金创始人Chamath
  5. android LinkedList的基本用法
  6. Android中Messenger的使用
  7. luogu1341 无序字母对
  8. Ospf在广播网络中建立邻居关系的详细过程
  9. 谈谈即时通讯开发平台
  10. maven 对于java的要求_如何在Maven中表达对Java EE功能的依赖以过渡到Java 9?
  11. 两年Java工作经验应该会些什么技术
  12. ❤️Bean的自动装配(详细)
  13. 机器学习基础(十六)—— bootstrap
  14. 极风云五里界IDC数据中心架构方案
  15. 红茶的功效与作用,喝红茶的好处和坏处,红茶的种类有哪些
  16. 不喜欢学计算机专业怎么办,录取到不喜欢的专业怎么办?说说我有所不同的“转系生活”...
  17. 变分法模型的运用:生产设备的最大经济效益
  18. springboot-vue前后端分离登录
  19. 1.8.ARM裸机第八部分-按键和CPU的中断系统
  20. 高手路过--菜鸟版系统安装==(图文安装教程)+(最新win7+win8系统)+系统工具

热门文章

  1. 天猫魔盒显示服务器响应错误,天猫魔盒网络连接异常 几招解决好这个问题
  2. 空降的大厂 CTO,半年内成功把团队带垮了!
  3. 推荐一款 Python 编辑器,集Pycharm和Sublime优点于一身的王者
  4. tb文件 vivado_Vivado IDDR与ODDR原语的使用
  5. java常见的注解之 @Documented、@Component
  6. 网易云音乐的消息队列改造,到底做了啥?
  7. 法师虽脆弱,但是升级刷怪经验要比其他角色快
  8. pdf压缩大小的简单方法
  9. 中国亚硝酸钠(案例7632-00-0)行业市场供需与战略研究报告
  10. Maven下载,安装与配置