并发编程实战(3): Thread 和 Runnable

写在前面

这两个一直放在一起比较,网上太多文章,关键有很多错误的,都是抄来抄去。

比如这篇文章我就觉得讲的不好,可以看评论区小白猿疼疼的评论,Runnable是只实例化一个类对象,开启三个线程去运行,而Thread是实例化三个类对象,在java中创建启动线程的唯一方法是调用它的start方法。 可以发现作者其实也没真正搞明白。关于文中的一个观点:实现Runnable可以资源共享,给出的代码例子并不能论证,或者说论证的不好。

Runnable

在实际应用中,都是建议多使用Runnable,主要原因还是在于其灵活性(flexibility),并不专注于线程的行为,只是让它运行。借鉴这篇博客中的一段话: 其他还有一些面向对象的思想,Runnable就相当于一个作业,而Thread才是真正的处理线程,我们需要的只是定义这个作业,然后将作业交给线程去处理,这样就达到了松耦合,也符合面向对象里面组合的使用,另外也节省了函数开销,继承Thread的同时,不仅拥有了作业的方法run(),还继承了其他所有的方法。综合来看,用Runnable比Thread好的多.

另外,Runnable是一个接口,我们都知道java只支持单继承,所以使用Runnable更符合java的哲学:Inherit less, interface more.

如果学的更深一些,会发现后面诸如FutureTask、 ThreadPoolExecutor等传递的都是Runnable对象。

Thread

很多博客将资源共享作为Runnable的优点之一,很明显太片面,因为Thread也可以资源共享,因为Thread本来就是实现了Runnable,包含Runnable的功能是很正常。

两者不宜非要比较不同

为这么这么说?因为这两者是相互依赖的,只实现Runnable接口是没法使用多线程的,因为没有start方法,还是要用Thread包装,两者的关系就像汽车的车轮和发动机一样。

实现接口Runnable时,意味着创建了可在不同线程中运行的对象(共享的原因),创建了一个可以在线程中运行的东西,不意味着创建了一个线程。可以说实现了Runnable接口的类只是一个带有run方法的普通类。如果不将其传递给Thread,其也不过只是带有run普通方法的普通对象。

Thread具有启动一个新线程的能力,通过其start方法实现了多线程。

对于实现多线程,可以简单来说需要两样东西:

  • 可以运行在线程中的东西(Runnable)
  • 可以启动一个线程的东西(Thread)

所以两者是必须的,像汽车启动需要发动机和车轮一样。因此,无法只用Runnable启动线程,而需要将其传递给一个Thead实例。

有人可能会疑问:不用Runnable,只用Thread也可以启动多线程啊。

这个前面已经说过了,因为Thread实现了Runnable,所以Thread也是一个Runnable。

比较好的参考资料

  1. https://howtodoinjava.com/java/multi-threading/java-runnable-vs-thread/
  2. https://stackoverflow.com/questions/541487/implements-runnable-vs-extends-thread-in-java?page=1&tab=votes#tab-top
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值