Thread和Runnable的区别和联系、多次start一个线程会怎么样

一、Java有两种方式实现多线程,第一个是继承Thread类,第二个是实现Runnable接口。他们之间的联系:

    1、Thread类实现了Runable接口。

  2、都需要重写里面Run方法。

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

 

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

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

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

看一下以继承Thread的卖票例子:

 
class MyThread extends Thread{  
    private int ticket = 5;  
    public void run(){  
    	 while(true){
    		 System.out.println("Thread ticket = " + ticket--);  
             if(ticket < 0){  
                break;
             }  
         }  
    }  
}  
public static void main(String[] args) {					
	new MyThread().start();
	new MyThread().start();
			
}

  输出结果:

Thread ticket = 5
Thread ticket = 5
Thread ticket = 4
Thread ticket = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 3
Thread ticket = 1
Thread ticket = 2
Thread ticket = 0
Thread ticket = 1
Thread ticket = 0

 从结果可以看出:创建了两个多线程对象,他们分别实现了买票任务; 

实现Runnable接口的卖票例子:

class MyThread2 implements Runnable{  
    private int ticket = 5;  
    public void run(){  
    	 while(true){
    		 System.out.println("Runnable ticket = " + ticket--);  
             if(ticket < 0){  
                break;
             }  
         } 
    }  
}  


<pre name="code" class="html">public static void main(String[] args) {
	MyThread2 m=new MyThread2();
	  new Thread(m).start();
	  new Thread(m).start();
		
			
}

输出结果:

1 Runnable ticket = 5
2 Runnable ticket = 4
3 Runnable ticket = 3
4 Runnable ticket = 2
5 Runnable ticket = 1
6 Runnable ticket = 0

从结果可以看出虽然我们声明了两个线程,但是一共卖了6张票。他们实现了资源共享。PS:在实际开发中,一定要注意命名规范,其次上面实现Runable接口的例子由于同时操作一个资源,会出现线程不安全的情况,如果情况需要,我们需要进行同步操作。

三、线程多次调用start方法,引发的异常  

   通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行。然后通过此Thread类调用方法run()来完成其运行操作的,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程终止,而CPU再运行其它线程,而如果直接用Run方法,这只是调用一个方法而已,程序中依然只有主线程--这一个线程,其程序执行路径还是只有一条,这样就没有达到写线程的目的。

  一个线程对象只能调用一次start方法.从new到等待运行是单行道,所以如果你对一个已经启动的线程对象再调用一次start方法的话,会产生:IllegalThreadStateException异常.

  可以被重复调用的是run()方法。
  Thread类中run()和start()方法的区别如下:
    run()方法:在本线程内调用该Runnable对象的run()方法,可以重复多次调用;
    start()方法:启动一个线程,调用该Runnable对象的run()方法,不能多次启动一个线程;

 

posted @ 2018-11-03 18:26  Java-live-begin  阅读(1387)  评论(0编辑  收藏  举报