彻底理解Runnable和Thread的区别
昨天去面试,面试官问了一个问题: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并没有什么区别。如果硬要说有什么区别的话,那就是类与接口的区别,继承与实现的区别。另外最重要的是,学习的时候不要忘了思考哦!
彻底理解Runnable和Thread的区别的更多相关文章
- Java中Runnable和Thread的区别
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...
- Android笔记——Handler Runnable与Thread的区别
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...
- Android开发笔记之:Handler Runnable与Thread的区别详解
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一 个类只要继承了Thread类同时覆写了本类中的run( ...
- Runnable和Thread的区别 (转)
在java中可有两种方式实现多线程,一种是继承 Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的 run ...
- 【转】java线程系列---Runnable和Thread的区别
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...
- java线程系列---Runnable和Thread的区别 (转载)
转自:http://blog.csdn.net/wwww1988600/article/details/7309070 在java中可有两种方式实现多线程,一种是继承 Thread类,一种是实现Run ...
- Java中Runnable和Thread的区别(转)
http://developer.51cto.com/art/201203/321042.htm 第一种方式:使用Runnable接口创建线程 第二种方式:直接继承Thread类创建对象 使用Runn ...
- runnable和thread的区别
一是写一个类继承自Thread类,然后重写里面的run方法,用start方法启动线程二是写一个类实现Runnable接口,实现里面的run方法,用new Thread(Runnable target) ...
- Runnable和Thread区别和比较
在很多博客中用这样一个例子来说明 Runnable更容易实现资源共享,能多个线程同时处理一个资源. 看代码: public static void main(String[] args) { new ...
随机推荐
- SQL盲注学习-布尔型
本次实验还是使用sqli-labs环境.在开始SQL盲注之前首先学习一下盲注需要用到的基础语法. 1.left()函数:left(str,lenth)它返回具有指定长度的字符串的左边部分. left( ...
- git 提交代码报错failed to push some refs to 解决笔记
Administrator@SC- MINGW64 /e/gitrepository (master) $ git push django master To github.com:zgc137/dj ...
- GoCN每日新闻(2019-10-31)
GoCN每日新闻(2019-10-31) GoCN每日新闻(2019-10-31) 1. Go语言继承的其他语言的优秀之处 https://spf13.com/presentation/the-leg ...
- js 创建xml元素
function createXML(pathData) { var xmlDOM = createXMLDOM(); //参考:http://iceworldvip.blog.51cto.com/5 ...
- Hadoop FairScheduler
目标 本文档描述FairScheduler,一个允许YARN应用程序公平共享集群资源的调度插件. 概述 公平调度是一个分配资源给所有application的方法,平均来看,是随着时间的进展平等分享资源 ...
- Zabbix实战-简易教程--中间件ZooKeeper监控
一.监控思路 通过zabbix trapper方式监控,之前看到网友们都是通过定时任务进行主动上传数据,但是,zabbix还有另外一神器--自动发现,也能达到同样的功能. 二.实现步骤 1.准备脚本 ...
- UE运行sas配置-WIN10
1.在UE中配置SAS运行的工具: UE--高级---用户工具--工具配置 在命令行输入"D:\soft\SASHome\SASFoundation\9.4\sas.exe" -c ...
- JPA的查询方法总结
一.使用where条件上一篇我们使用JPA进行了数据源的访问,默认JPA已经实现了好几个接口可以调用.但是,在实际的业务中,查询语句不可避免地需要使用where.order by等语句. 我们用商品数 ...
- 往hbase插入数据,你会选择哪种?
好久,好久没有写个博客了,自从上次封闭开始,到“自闭”,有了一段时间了,哈哈^_^ . 多亏了云桌面的歇菜, 一下午啥都干不了, 突然想到,好久没有写点啥了,就写的,让时间流走有点痕迹吧 _(:з」∠ ...
- spring的multipartResolver和java后端获取的MultipartHttpServletRequest方法对比
这两天在用spring进行上传上遇到问题,今天进行了问题的排查,这个过程也增加了我看spring源码的兴趣!还是很有收获的! 首先先给A组提供了上传接口,并没有在spring的配置文件进行multip ...