多线程继承Thread和实现Runnable的区别

本文总阅读量

执行原理

转自:http://blog.chinaunix.net/uid-20665441-id-310538.html

实现Runnable的好处

转自:http://www.oschina.net/question/565065_86563

可见, 实现Runnable接口相对于继承Thread类来说,有如下显著的好处:

(1)适合多个相同程序代码的线程去处理同一资源的情况,把虚拟CPU(线程)同程序的代码,数据有效的分离,较好地体现了面向对象的设计思想。

(2)可以避免由于Java的单继承特性带来的局限。我们经常碰到这样一种情况,即当我们要将已经继承了某一个类的子类放入多线程中,由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么,这个类就只能采用实现Runnable接口的方式了。

(3)有利于程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码。多个线程操作相同的数据,与它们的代码无关。当共享访问相同的对象是,即它们共享相同的数据。当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable接口的类的实例。

自己的思考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class runnableThread implements Runnable {
private int ticket = 10;

@Override
public void run() {
for (int i = 0; i < 10; i++) {
//synchronized (this) {

if (this.ticket > 0) {
//synchronized (this) {
System.out.println("卖票:ticket" + this.ticket-- + " ---当前线程id:"
+ Thread.currentThread().getId()
+ "---余票"+ticket);
//}
/*try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
*/

}
}
}

public static void main(String[] args) {
runnableThread mt1 = new runnableThread();
runnableThread mt2 = new runnableThread();
runnableThread mt3 = new runnableThread();

new Thread(mt1).start();// 启动了三个线程共享那一个类里面的数据
new Thread(mt1).start();
new Thread(mt1).start();
}
}

上述代码run()方法中,如果Thread.sleep(100),则买票时会出现问题,如:第10张票被卖了2次。

保证安全的方法:把卖票的步骤用synchronized包起来。那么就不会出问题了。