在Java中,实现多线程有两种方式,分别是:
-
实现Runnable接口实例化Thread类
-
继承Thread类重写run()方法
两个方法均可实现多线程操作,但是还是存在局部的差异,下面通过代码来演示一下:
实现Runnable接口
public class MyRunnable implements Runnable{
private int count = 10;
@Override
public void run() {
for(int i=1; i<=10; i++) {
if(this.count > 0) {
System.out.println(Thread.currentThread().getName() + this.count--);
}
}
}
public static void main(String[] args) {
MyRunnable run = new MyRunnable();
Thread thread1 = new Thread(run,"1号线程:");
Thread thread2 = new Thread(run,"2号线程:");
Thread thread3 = new Thread(run,"3号线程:");
// 实例化新的线程对象 -> 每个线程对象的属性和方法都是独立的,效果等同继承Thread类。
// Thread thread1 = new Thread(new MyRunnable(),"1号线程:");
// Thread thread2 = new Thread(new MyRunnable(),"2号线程:");
// Thread thread3 = new Thread(new MyRunnable(),"3号线程:");
// 启动线程
thread1.start();
thread2.start();
thread3.start();
}
}
运行结果:
1号线程:10
3号线程:8
2号线程:9
3号线程:6
1号线程:7
3号线程:4
3号线程:2
3号线程:1
1号线程:3
2号线程:5
继承Thread类
public class MyThread extends Thread{
private int count = 10;
private String name;
public MyThread() {}
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
for(int i=1; i<=10; i++) {
System.out.println(this.name + this.count--);
}
}
public static void main(String[] args) {
MyThread thread1 = new MyThread("1号线程:");
MyThread thread2 = new MyThread("2号线程:");
MyThread thread3 = new MyThread("3号线程:");
// 启动线程
thread1.start();
thread2.start();
thread3.start();
}
}
运行结果:
3号线程:10
2号线程:10
1号线程:10
2号线程:9
2号线程:8
3号线程:9
2号线程:7
1号线程:9
2号线程:6
3号线程:8
2号线程:5
1号线程:8
2号线程:4
2号线程:3
3号线程:7
2号线程:2
1号线程:7
2号线程:1
3号线程:6
3号线程:5
3号线程:4
1号线程:6
3号线程:3
3号线程:2
3号线程:1
1号线程:5
1号线程:4
1号线程:3
1号线程:2
1号线程:1
总结
可以发现,实现Runnable
接口的方式创建的线程是资源共享的(同时使用了一个实现了Runnable接口的对象,可以理解为start()执行时,只是单纯调用了其中的run方法。两者联系见:https://blog.csdn.net/tornado886/article/details/4524346 )。
继承Thread
类方式创建的线程,其本质是实例化了一个新的对象,所以其属性与方法是相互独立的,由于这个特性,其不适合资源共享。(可以在类中声明static修饰的静态成员变量解决这个问题)
如果只想重写run()方法,而不重写其他Thread方法,那么应使用Runnable接口。除非修改或增强类的基本行为,否则不应该使用继承Thread类的方式实现多线程。