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

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

    一、Thread类实现了Runable接口。html

  二、都须要重写里面Run方法。java

2、实现Runnable接口相对于继承Thread类来讲,有以下显著的好处:

 

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

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

  三、有利于程序的健壮性,代码可以被多个线程共享,代码与数据是独立的。当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码。多个线程操做相同的数据,与它们的代码无关。当共享访问相同的对象是,即它们共享相同的数据。当线程被构造时,须要的代码和数据经过一个对象做为构造函数实参传递进去,这个对象就是一个实现了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

 从结果能够看出:建立了两个多线程对象,他们分别实现了买票任务; spa

实现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接口的例子因为同时操做一个资源,会出现线程不安全的状况,若是状况须要,咱们须要进行同步操做。code

3、线程屡次调用start方法,引起的异常  

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

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

  能够被重复调用的是run()方法。
  Thread类中run()和start()方法的区别以下:
    run()方法:在本线程内调用该Runnable对象的run()方法,能够重复屡次调用;
    start()方法:启动一个线程,调用该Runnable对象的run()方法,不能屡次启动一个线程;
相关文章
相关标签/搜索