昨天去面试,面试官问了一个问题:Runnable和Thread有什么区别,因为针对这个问题以前有背过,并且网上大多数都是这些结论,所以脱口而出:

1.Thread有单继承的问题;
2.Runnable便于实现资源共享,而Thread不能;

然而面试官好像并没有什么表示。之后结束后我就找了一下度娘,得到了这篇文章:

https://blog.csdn.net/zhaojianting/article/details/97664370

突然发现“Runnable便于实现资源共享”这一优点好像并不合理,以下是我的代码实现。

使用Thread实现多线程

public class MyThread extends Thread {

    private int ticket = 5;

    @Override
public void run() {
while (true) {
System.out.println("Thread ticket = " + ticket--);
if (ticket < 0) {
break;
}
}
} } public class Test {
public static void main(String[] args) { //Test Thread new MyThread().start();
new MyThread().start(); }
} 执行结果如下:
Thread ticket = 5
Thread ticket = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 1
Thread ticket = 0
Thread ticket = 5
Thread ticket = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 1
Thread ticket = 0

并不能实现资源共享,跟以前背的面试题答案一样;但真的是这样吗?我们仔细看一下,代码中我们创建了两个MyThread对象,每个对象都有自己的ticket成员变量,当然会多卖1倍。现在我们重新测试一下,请看测试代码:

public class Test {
public static void main(String[] args) { //Test Thread MyThread t1 = new MyThread();
new Thread(t1).start();
new Thread(t1).start();
}
} 测试结果如下:
Thread ticket = 5
Thread ticket = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 1
Thread ticket = 0
Thread ticket = -1

可以看到这次我们只创建了一个MyThread对象,并没出现卖两倍票的情况,Thread也可以实现资源共享。

因为多线程访问同一变量会有并发问题(需要加锁),所以Thread正确的写法如下:

public class MyThread extends Thread {

    private int ticket = 5;

    @Override
public void run() {
if (ticket > 0) {
synchronized (this) {
if (ticket > 0) {
while (true) {
System.out.println("Thread:" + Thread.currentThread().getName() + "--Thread ticket = " + ticket--);
if (ticket < 0) {
break;
}
}
}
}
}
} } public class Test {
public static void main(String[] args) { //Test Thread MyThread t1 = new MyThread();
new Thread(t1).start();
new Thread(t1).start();
new Thread(t1).start();
new Thread(t1).start();
new Thread(t1).start();
new Thread(t1).start();
}
} 执行结果如下:
Thread:Thread-1--Thread ticket = 5
Thread:Thread-1--Thread ticket = 4
Thread:Thread-1--Thread ticket = 3
Thread:Thread-1--Thread ticket = 2
Thread:Thread-1--Thread ticket = 1
Thread:Thread-1--Thread ticket = 0

现在看Thread和Runnable的源码:


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; @FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}

结论:其实Thread也就是实现了Runnable接口,提供了更多的方法而已。所以说Thread与Runnable并没有什么区别。如果硬要说有什么区别的话,那就是类与接口的区别,继承与实现的区别。另外最重要的是,学习的时候不要忘了思考哦!

最新文章

  1. 思达index网站
  2. 移动端web app自适应布局探索与总结
  3. 创建下拉列表并通过ajax填充下拉数据
  4. php对xml的处理
  5. Android开发华为手机无法看log日志解决方法
  6. EasyUI Messager 消息框
  7. [译]Selenium Python文档:六、页面对象
  8. tensorflow softsign函数应用
  9. 【Python3爬虫】用Python中的队列来写爬虫
  10. 启用chacha20和salsa20等加密方法
  11. linux 过滤内存使用率并于计划任务结合来自动清理内存缓存
  12. 牛客网练习赛t2(线段树)
  13. Nginx访问权限配置
  14. 使用quicklz缩小程序体积
  15. 常用for循环和for in 以及for of 的区别
  16. Luffy之前端项目部署搭建
  17. 【Jmeter自学】Jmeter作用域(五)
  18. Oracle 学习总结 - 内存优化
  19. Codeforces 545E. Paths and Trees 最短路
  20. 20155227 2016-2017-2 《Java程序设计》第九周学习总结

热门文章

  1. Thanos prometheus 集群以及多租户解决方案docker-compose 试用(一)
  2. 如果设置Redis客户端的超时时长?
  3. 花了两个星期,我终于把 WSGI 整明白了
  4. nginx php-fpm 配置问题(2)
  5. create-react-app项目暴露webpack配置文件
  6. poi导出word表格跨行
  7. QC9.2登陆时显示一个X号
  8. SDN实验---Ryu的应用开发(三)流量监控
  9. windows下ffmpeg批量转码
  10. Tplink路由器怎么设置无线桥接(转载)