Runnable和Thread比较
看代码
public static void main(String[] args) {
// TODO Auto-generated method stub
new MyThread().start();
new MyThread().start();
}
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 = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 3
Thread ticket = 1
Thread ticket = 2
Thread ticket = 0
Thread ticket = 1
Thread ticket = 0
这样多卖了一半的票显然不合理,用runnable试试:
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread2 m=new MyThread2();
new Thread(m).start();
new Thread(m).start();
}
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 = 2
Runnable ticket = 1
Runnable ticket = 0
这样的结果才合理。 很明显这个例子完全错误,多卖票的原因根本不是因为Runnable和Thread的区别,看调用就知道了。 使用Thread的时候是这样调用的:
new MyThread().start();
new MyThread().start();
而使用Runnable的时候是这样调用的:
new Thread(m).start();
new Thread(m).start();
新建了两个MyThread对象去卖票,不卖两倍票才怪呢,而Runnable卖票的时候是同一个Runnable对象,肯定只卖一倍票,所以这个例子根本没体现Runnable和Thread的区别,再来看一个例子:
public class TicketThread 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){
TicketThread t1 = new TicketThread();
new Thread(t1,"线程1").start();
new Thread(t1,"线程2").start();
}
}
输出结果:
线程1卖票—->10
线程1卖票—->9
线程1卖票—->8
线程2卖票—->7
线程2卖票—->6
线程1卖票—->5
线程1卖票—->4
线程2卖票—->3
线程2卖票—->2
线程1卖票—->1
(这里必须使用synchronized,否则会出现重复卖某一张票的情况,当然这点和本篇文章无关,这里不做详述。) 这样就达到了卖一倍票的结果,没毛病。这样看起来,Thread和Runnable岂不是没区别了? 找到答案很简单,点进去看Thread源码就知道了
public class Thread implements Runnable {}
可以看出,Thread实现了Runnable接口,这和上面例子中的MyThread2一样了,当我们使用
TicketThread t1 = new TicketThread();
new Thread(t1,"线程1").start();
这种写法时,会被认为智障。。。。没错,就是智障,这是脱裤子放屁的写法,标准写法应该是:
TicketThread t1 = new TicketThread();
t1.start();
看看源码:
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
new Thread( new TicketThread(),"线程1").start();这种写法里面,TicketThread会被当做一个Runnable,那我还要写一个TicketThread类干嘛?所以这就是脱裤子放屁。 说了这么多,那两者的区别到底是什么? 来看看Runnable的代码:
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();
}
结论就是:
1、效果上没区别,写法上的区别而已。 2、没有可比性,Thread实现了Runnable接口并进行了扩展,我们通常拿来进行比较只是写法上的比较,而Thread和Runnable的实质是实现的关系,不是同类东西。
无论你使用Runnable还是Thread,都有一个new Thread的过程,效果上最后都是new Thread,然后执行run方法。写法上的区别无非就是你是new Thead还是new你自定义的thread,如果你有复杂的线程操作需求,那就自定义Thread,如果只是简单的在子线程run一下任务,那就自己实现runnable,当然如果自己实现runnable的话可以多一个继承(自定义Thread必须继承Thread类,java单继承规定导致不能在继承别的了)。
- Android新组件RecyclerView介绍,其效率更好
- android wheelview实现三级城市选择
- 算法之冒泡排序
- 数据结构之链表
- Spring Cloud实战小贴士:Zuul统一异常处理(三)【Dalston版】
- 算法之红黑树
- MIDlet工作原理
- 第五章 正则表达式的拆分【修订】
- 仿今天头条加载环境文字闪动效果
- Myexclipse创建Junit测试
- 基于ASP.NET MVC(C#)和Quartz.Net组件实现的定时执行任务调度
- 第五章 正则表达式的拆分
- android 防止反编译的若干方法
- 支持Ajax跨域访问ASP.NET Web Api 2(Cors)的简单示例教程演示
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法