浅谈Java多线程之Threa类和Runnable接口的区别

众所周知Java多线程通过两种方式创建:一种是继承Thread类,另一种是实现Runnable接口。那么,两种方式有什么区别?哪种方式更好些?  

Thread类定义在Java.lang包中,只要继承Thread类同时覆写本类的run()方法就能操作多线程,但一个类只能继承一个父类,这是继承Thread类的局限。

Thread类示例:

class Test extends Thread{  
	private String name;  
	public Test(String name){  
		super();
		this.name = name;
	}  
	public void run(){  
		for(int i=0;i<10;i++){  
			System.out.println("线程启动:"+this.name+",i="+i);  
		}  
	}  
}   
public class ThreadTest{  
	public static void main(String[] args){  
		Test t1=new Test("线程A");  
		Test t2=new Test("线程B");  
		t1.run();  
		t2.run();  
	}  
}

结果很有规律,第一个对象先执行,然第二个对象再执行,并没有相互交替运行,说明线程没启用,只是普通的方法调用。查看JDK文档发现一旦调用start()方法,则通过JVM找到run()方法启动线程。

public class ThreadTest{  
	public static void main(String[] args){  
		Test t1=new Test("线程A");  
		Test t2=new Test("线程B");  
		t1.start();  
		t2.start();  
	}  
}

这样程序能正常完成交互式运行,为什么非要使用start()方法启动多线程?

在JDK安装目录下,src.zip是Java源程序,通过此找到Thread类的start()方法的定义,发现使用private native void start();其中native关键字表示允许调用操作系统的底层函数,这样的技术称为JNI技术(Java Native Interface)。

Runnabl接口示例:

实际开发中多线程操作较少使用Thread类,主要通过Runnable接口完成。

class Test implements Runnable{  
	private String name;  
	public Test(String name){  
		this.name = name;
	}  
	public void run(){  
		for(int i=0;i<10;i++){  
			System.out.println("线程启动:"+this.name+",i="+i);  
		}  
	}  
}   
public class RunnableTest{  
	public static void main(String[] args){  
		Test t1 = new Test("线程1");
		Test t2 = new Test("线程2");
		new Thread(t1).start();
		new Thread(t2).start();		
	}  
}

使用Runnable接口定义的子类没有start()方法,只有Thread类中才有。通过JDK文档查看Thread类有一构造方法:Public Thread(Runnable targer)接受Runnable的子类实例,也就是说通过Thread类启动start()方法实现Runnable的多线程。

两种实现方式的区别和联系:

程序开发中多线程永远以实现Runnable接口为主,因为和继承Thread类相比有如下好处:

1、避免单继承的局限,Java中一个类允许实现多个接口;

2、适合于资源的共享。

Thread类卖票程序:

class Ticket extends Thread{
	private int tick=10;
	public void run(){
		while(true){
			if(tick>0)
				System.out.println(Thread.currentThread().getName()+"...SaleTikcet...."+tick--);
		}
	}
}
class TicketDemo{
	public static void main(String[] args)	{
		Ticket t1 = new Ticket();
		Ticket t2 = new Ticket();
		Ticket t3 = new Ticket();
		t1.start();//每个线程都各卖10张,共计30张票,
		t2.start();//实际只有10张票,每个线程都各卖各的,
		t3.start();//没有达到资源共享目的。
	}
}
如果用Runnable接口就能实现资源共享,示例如下:

class Ticket implements Runnable{
	private int tick = 10;
	public void run(){
		while(true){
			if(tick>0)
			{			
				System.out.println(Thread.currentThread().getName()+"...SaleTicket..."+tick--);
			}
		}
	}
}
class TicketDemo2{
	public static void main(String[] args){
		Ticket t = new Ticket();		
		new Thread(t).start();//同一t,在Thread类中不可以,
		new Thread(t).start();//如果同一个实例化对象,会报异常。
		new Thread(t).start();	
	}
}
现在程序中有三个线程,但一共只卖了10张票,达到了资源共享目的。

通过查看JDK文档发现:public class Thread extends Object implements Runnable ,说明Thread类也是Runnable接口的子类。 


PS:初碰Java,网上搜索到许多这样的文章;口语化严重,措辞生硬晦涩, 忍不住想整改。借用模板重新编写,原作者不详,看到请告之。

 

 

 

 

 

 

 

你可能感兴趣的:(浅谈Java多线程之Threa类和Runnable接口的区别)