彻底理解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 ...
随机推荐
- learning shell monitor prog function
[Purpose] Shell script monitor prog function [Eevironment] Ubuntu 16.04 bash env [ ...
- javascript优先级注意点
javascript 优先级 注意一下 && 和 == 号之间的优先级关系 请首先看如下代码, 判断下 && 和 == 的优先级 const emptyObj = {n ...
- pwd函数实现
/* * 文件名:mypwd.c * 描述: 实现简单的pwd命令 */ #include<stdio.h> #include<stdlib.h> #include<di ...
- 5098: [BZOJ1098][POI2007]办公楼biu
5098: [BZOJ1098][POI2007]办公楼biu 没有数据结构就很棒 一个看上去非常玄学的代码 const int N=1e5+10,M=2e6+10; int n,m; int fa[ ...
- Python开发:OpenCV版本差异所引发的cv2.findContours()函数传参问题
一.问题如下: cv2.findContours()这个方法是用来找出轮廓值的: # cv2.findContours找出轮廓值,cv2.RETR_EXTERNAL表示图像的外轮廓 binary, c ...
- Java中的锁原理、锁优化、CAS、AQS详解!
阅读本文大概需要 2.8 分钟. 来源:jianshu.com/p/e674ee68fd3f 一.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 二.锁实现的基本原理 2.1.v ...
- java基础之 clone
参考文档:深拷贝&浅拷贝:http://blog.csdn.net/cws1214/article/details/52193341 克隆的分类: (1)浅克隆(shallow clone) ...
- Xshell远程登录
1.xshell由一台服务器a登录另一台服务器b sftp -oPort = root@ip 2.下载git /上传pull git b服务器想下载的目标文件目录 a服务器上的文件下载目录
- 【Beta】Scrum meeting 4
目录 写在前面 进度情况 任务进度表 Beta-1阶段燃尽图 遇到的困难 照片 commit记录截图 小程序前端仓库 技术博客 写在前面 例会时间:5.8 22:30-23:00 例会地点:微信群语音 ...
- BIND配置
一,简介 相对于存储和大数据领域,CDN是一个相对小的领域,但行行出状元,BIND就是CDN领域的蝉联N届的状元郎.BIND是一款非常常用的DNS开源服务器,全球有90%的DNS用BIND实现.值得一 ...