3.多线程两种实现方式的区别
1.面试题:Thread类和Runnable接口实现多线程的区别?(多线程两种实现的区别?)
1).Thread类是Runnable接口的子类,使用Runnable接口可以避免单继承局限。
2).Runnable接口实现多线程可以比Thread类实现多线程,更加清楚的描述数据共享的概念。
1.1 Thread是Runnable的子类,使用Runnable可以避免单继承局限
查看Thread类源码如下:
public class Thread extends Object implements Runnable
Thread类,实现了Runnable接口,整体定义机构看起来像代理设计模式;
代理模式:客户端调用的start方法应该是Runnable接口提供的方法才对。
1.2 Runnable比Thread实现多线程更加清楚的描述数据共享的概念
Thread实现的多线程如下:
public class MyThread extends Thread{
private int money=10;
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (money > 0) {
System.out.print("购物,mony = " + this.money-- + ";");
}
}
}
}
class TestThread{
public static void main(String[] args) {
MyThread m1= new MyThread();
MyThread m2= new MyThread();
MyThread m3= new MyThread();
m1.start();
m2.start();
m3.start();
}
}
看看多线程这部分有问题吗?看下启动多线程的代码的内存分布情况如下
这样写的结果肯定是不是共享这个10元,而是每进程10元,应该修改为如下调用方式:
class TestThread{
public static void main(String[] args) {
MyThread m1= new MyThread();
new Thread(m1).start();
new Thread(m1).start();
new Thread(m1).start();
}
}
修改后的代码看着总是怪怪的,MyThread类直接就可以调用start方法,却不用,创建父类对象调用start方法,有点舍近求远的意思。
Runnable实现多线程代码如下
public class MyRunnable implements Runnable{
private int mony=10;
@Override
public void run() {
for(int i=0;i<100;i++){
if(mony>0) {
System.out.print("购物,mony = " + this.mony--+";");
}
}
}
}
class TestRunnable{
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
new Thread(myRunnable).start();
new Thread(myRunnable).start();
new Thread(myRunnable).start();
}
}
这段代码的内存分布图如下:
从代码上Runnable接口实现多线程,可以更加清楚的描述数据共享的概念。