(一) Java中Runnable和Thread
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。
1.Thread
示例代码:
package org.thread.demo; class MyThread extends Thread{ private String name; public MyThread(String name) { super(); this.name = name; } public void run(){ for(int i=0;i<10;i++){ System.out.println("线程开始:"+this.name+",i="+i); } } } package org.thread.demo; public class ThreadDemo01 { public static void main(String[] args) { MyThread mt1=new MyThread("线程a"); MyThread mt2=new MyThread("线程b"); //mt1.run(); //mt2.run(); mt1.start(); mt2.start(); } }
调用start和run的区别:start()方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码:通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程终止,而CPU再运行其它线程
run()方法当作普通方法的方式调用,程序还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码:而如果直接用Run方法,这只是调用一个方法而已, 程序中依然只有主线程--这一个线程, 其程序执行路径还是只有一条,这样就没有达到写线程的目的。
2.Runnable 接口
该接口只有一个方法:public void run(),实现该接口的类必须重写该方法。实现了Runnable接口的类并不具备任何天生的线程处理能力,这与从Thread类继承的类是不同的。为了从一个Runnable对象产生线程,必须再单独创建一个线程对象,并把Runnable对象传递给它。
示例代码:
1 package org.runnable.demo; 2 class MyThread implements Runnable{ 3 private String name; 4 public MyThread(String name) { 5 this.name = name; 6 } 7 public void run(){ 8 for(int i=0;i<100;i++){ 9 System.out.println("线程开始:"+this.name+",i="+i); 10 } 11 } 12 }; 13 package org.runnable.demo; 14 import org.runnable.demo.MyThread; 15 public class ThreadDemo01 { 16 public static void main(String[] args) { 17 MyThread mt1=new MyThread("线程a"); 18 MyThread mt2=new MyThread("线程b"); 19 new Thread(mt1).start(); 20 new Thread(mt2).start(); 21 } 22 }
3.区别和联系
在程序中一般以实现Runnable接口为主,主要从以下几点考虑:1.避免Thread继承的局限;2.资源共享
以下sale ticket 程序为例:
1 package org.demo.dff; 2 class MyThread extends Thread{ 3 private int ticket=10; 4 public void run(){ 5 for(int i=0;i<20;i++){ 6 if(this.ticket>0){ 7 System.out.println("卖票:ticket"+this.ticket--); 8 } 9 } 10 } 11 }; 12 13 package org.demo.dff; 14 public class ThreadTicket { 15 public static void main(String[] args) { 16 MyThread mt1=new MyThread(); 17 MyThread mt2=new MyThread(); 18 MyThread mt3=new MyThread(); 19 mt1.start();//每个线程都各卖了10张,共卖了30张票 20 mt2.start();//但实际只有10张票,每个线程都卖自己的票 21 mt3.start();//没有达到资源共享 22 } 23 } 24 25 如果用Runnable就可以实现资源共享,下面看例子: 26 package org.demo.runnable; 27 class MyThread implements Runnable{ 28 private int ticket=10; 29 public void run(){ 30 for(int i=0;i<20;i++){ 31 if(this.ticket>0){ 32 System.out.println("卖票:ticket"+this.ticket--); 33 } 34 } 35 } 36 } 37 package org.demo.runnable; 38 public class RunnableTicket { 39 public static void main(String[] args) { 40 MyThread mt=new MyThread(); 41 new Thread(mt).start();//同一个mt,但是在Thread中就不可以,如果用同一 42 new Thread(mt).start();//个实例化对象mt,就会出现异常 43 new Thread(mt).start(); 44 } 45 }; 46 虽然现在程序中有三个线程,但是一共卖了10张票,也就是说使用Runnable实现多线程可以达到资源共享目的。
摘自:http://developer.51cto.com/art/201203/321042.htm
示例:http://bijian1013.iteye.com/blog/1871745