Java多线程的三种实现方式(重点看Collable接口实现方式)

1、通过继承Thread类来实现多线程

              在继承Thread类之后,一定要重写类的run方法,在run方法中的就是线程执行体,在run方法中,直接使用this可以获取当前线程,直接调用getName()方法可以获得当前线程的名称,多线程的名称一般为Thread-n。而在主方法中,需要调用Thread.currentThread()方法来获取当前线程。需要注意的是,主线程(从主方法main开始执行的线程)也是一个线程。main方法中的内容代表的是主线程的线程执行体。

              在Thread对象创建完成之后,要调用start方法来启动线程对象。

[java]  view plain  copy
  1. public class ThreadName extends Thread  
  2. {  
  3.     private int i ;  
  4.     public void run()  
  5.     {  
  6.         for ( ; i < 100 ; i++ )  
  7.         {  
  8.             System.out.println(getName() + i);  
  9.         }  
  10.     }  
  11.     public static void main(String[] args)   
  12.     {  
  13.         for (int i = 0; i < 100;  i++)  
  14.         {  
  15.             System.out.println(Thread.currentThread().getName() + i);  
  16.             if (i == 20)  
  17.             {  
  18.                 // 创建、并启动两条线程  
  19.                 new ThreadName().start();  
  20.                 new ThreadName().start();  
  21.             }  
  22.         }  
  23.     }  
  24. }  

2、通过实现Runnable接口来实现多线程

              同样的,当实现了Runnable接口之后,要重写接口中的run方法,否则会报错。run方法中的代码块儿就是线程执行体。但是,此时在run方法中想要获得当前线程,必须使用Threa.currentThread ()方法。在主线程中如果需要启动新的线程,其创建的方法也与直接继承Thread类有区别。需要首先创建Runnable实现类的实例,然后左右Thread的Target来创建Thread对象,这个对象才是真正的线程对象,实际的线程对象依然是Thread实例,只是这个Thread线程负责执行target对象的run()方法。完成之后再调用start方法来启动线程对象。

[java]  view plain  copy
  1. public class ThreadName implements Runnable  
  2. {  
  3.     private int i ;  
  4.   
  5.     public void run()  
  6.     {  
  7.         for ( ; i < 100 ; i++ )  
  8.         {  
  9.             System.out.println(Thread.currentThread().getName() + i);  
  10.         }  
  11.     }  
  12.           
  13.     public static void main(String[] args)   
  14.     {  
  15.         for (int i = 0; i < 100;  i++)  
  16.         {  
  17.             System.out.println(Thread.currentThread().getName()  
  18.                 + "  " + i);  
  19.             if (i == 20)  
  20.             {  
  21.                 ThreadName st = new ThreadName();     
  22.                 // 通过new Thread(target , name)方法创建新线程  
  23.                 new Thread(st , "新线程1").start();  
  24.                 new Thread(st , "新线程2").start();  
  25.             }  
  26.         }  
  27.     }  
  28. }  

3、通过实现Collable接口来实现线程

              当实现Callable接口之后,要重写接口中的call方法,call方法中的代码作为线程执行体,此时的call方法可以有返回值。

              Callable接口是Java5中新增的接口,不是Runnable接口的子接口,所以Callable对象不能直接作为Thread对象的Target,于是Java5中提供了Future接口来代表Callable接口里call方法的返回值,并为Future接口提供了一个FutureTask实现类,它实现了Future接口和Runnable接口,可以作为Thread类的Target。所以在创建Callable

接口实现类之后,要用FutureTask来包装Callable对象(实现手动装箱)。然后用FutureTask对象作为Target。

[java]  view plain  copy
  1. public class ThreadName implements Callable<Integer>  
  2. {  
  3.     public Integer call()  
  4.     {  
  5.         int i = 0;  
  6.         for ( ; i < 100 ; i++ )  
  7.         {  
  8.             System.out.println(Thread.currentThread().getName() + "的循环变量i的值:" + i);  
  9.         }  
  10.         // call()方法的返回值  
  11.         return i;  
  12.     }  
  13.   
  14.     public static void main(String[] args)   
  15.     {  
  16.         // 创建Callable对象  
  17.         ThreadName rt = new ThreadName();  
  18.         // 使用FutureTask来包装Callable对象  
  19.         FutureTask<Integer> task = new FutureTask<Integer>(rt);  
  20.         for (int i = 0 ; i < 100 ; i++)  
  21.         {  
  22.             System.out.println(Thread.currentThread().getName() + "的循环变量i的值:" + i);  
  23.             if (i == 20)  
  24.             {  
  25.                 // 实质还是以Callable对象来创建、并启动线程  
  26.                 new Thread(task , "有返回值的线程").start();  
  27.             }  
  28.         }  
  29.         try  
  30.         {  
  31.             // 获取线程返回值  
  32.             System.out.println("子线程的返回值:" + task.get());  
  33.         }  
  34.         catch (Exception ex)  
  35.         {  
  36.             ex.printStackTrace();  
  37.         }  
  38.     }  
  39. }  


注明: 以上代码和解释部分来自“疯狂Java讲义(李刚)”。

上面三种创建方式都可以实现多线程,后面两种很相似,只不过Callable接口中的call方法可以有返回值,可以声明抛出异常。

一般在实际的代码中,推荐使用实现Runnable接口或者Callable接口的方式来实现多线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值