Java多线程定义方式可以通过继承Thead实现, 也可以通过实现Runable接口实现,它们之间关系如下图:
Thead类实际上是Run able类的实现类,所以最后不管是使用哪种方式,最终都是通过Thread类从OS申请资源分配启动线程;
下面的3段代码中,前2个效果等价:
class MyThread extends Thread {
private int i = 0;
@Override
public void run() {
for (i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
public class Test{
public static void main(){
MyThread mt1= new MyThread();
MyThread mt2= new MyThread();
MyThread mt3= new MyThread();
mt1.start();
mt2.start();
mt3.start();
}
}
class MyThread implements Runable {
private int i = 0;
@Override
public void run() {
for (i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
public class Test{
public static void main(){
MyThread mt1= new MyThread();
MyThread mt2= new MyThread();
MyThread mt3= new MyThread();
new Thread(mt1).start();
new Thread(mt2).start();
new Thread(mt3).start();
}
}
上面2中方式的内存空间分配上等价,如下图,:
下面的多线程方式体现了使用Runable更适合实现资源(例如 访问同一实例)共享, 但事物总是有两面性,这种场景也会带来线程安全相关问题,代码示例如下:
class MyThread implements Runable {
private int i = 0;
@Override
public void run() {
for (i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
public class Test{
public static void main(){
MyThread mt= new MyThread();
new Thread(mt).start();
new Thread(mt).start();
new Thread(mt).start();
}
}
总结实现Runnable接口比继承Thread类所具有的优势:
1)适合多个相同的程序代码的线程去处理同一个资源(同时也可能引入线程安全问题)
2)可以避免java中的单继承的限制
没有评论