Java中Thread与Runnable的对比区别,并实现资源共享问题、
Java中实现多线程有两种方式,一种是继承Thread类,另一种是实现Runnable接口。Thread是继承类,而我们知道继承是单继承,所以很有局限性;而实现Runnable接口可以多实现,具有多选择性。
那么,对于一个线程,这两个有什么区别?如何用实现Runnable接口来实现资源共享?
现在用一个模拟售票系统来分析对比:
1,继承Thread类,实现多线程:
public class MyThread extends Thread{
private int ticket = 10;
@Override
public void run() {
super.run();
while(true){
if (ticket>0) {
System.out.println(Thread.currentThread().getName()+"出票一张"+ticket--);
}
}
}
}
这里定义十张票,用一个Thread线程来处理,接下来写一个测试方法,在测试中实例化三个类来处理,开启三个线程来处理:
@Test
public void test(){
MyThread myThread = new MyThread();
myThread.start();
MyThread myThread2 = new MyThread();
myThread2.start();
MyThread myThread3 = new MyThread();
myThread3.start();
我们可以看下这个代码运行的结果:
很明显,这种方式是错误的,因为在每一个类中都有去处理10张票,等于有三十张票。所以可以理解我一个多线程去各自的任务。而我们这里要的是多线程去处理一个任务,显然这种方式时不行的。但是要用Thread实现多线程处理一个任务也可以实现,只是相对复杂。
下面用实现Runnable接口来实现:
写一个类来实现Runnable接口,代码如下:
public class MyRunnable implements Runnable{
private int ticket = 10;
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()+"出票一张"+ticket--);
}
}
}
}
然后写一个方法来测试结果:
@Test
public void testRunnable(){
MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr,"一号窗口");
Thread t2 = new Thread(mr,"二号窗口");
Thread t3 = new Thread(mr,"三号窗口");
Thread t4 = new Thread(mr,"四号窗口");
t1.start();
t2.start();
t3.start();
t4.start();
}
而这里你会发现,我们在这实例化了一个MyRunnable类,然后开启三个线程去执行这个任务,看结果:
ok,完美,这就是一个多线程共同完成一个任务,实现资源共享。
接下来,看另外一种情况,我们用三个线程执行三个任务:
测试方法如下:
@Test
public void testRunnable2(){
Thread t1 = new Thread(new MyRunnable(),"一号窗口");
Thread t2 = new Thread(new MyRunnable(),"二号窗口");
Thread t3 = new Thread(new MyRunnable(),"三号窗口");
Thread t4 = new Thread(new MyRunnable(),"四号窗口");
t1.start();
t2.start();
t3.start();
t4.start();
}
那么,我们来看结果:
可以看到,结果跟一个例子是一样的,这并没有实现资源共享的效果。
最后,看看这张图,你就会明白一种方法和第二种方法的结果的区别: