并发编程学习总结(一) :java 创建线程的三种方式的优缺点和实例(转载自:http://blog.csdn.net/u011784767/article/details/51315007)

Java 创建线程有三种方式:

(一)  实现Runnable接口  

       优点:(1) 创建线程的同时可以继承其他的类,从而可以扩展类的功能。

                  (2) 同一个实现Runnable接口的实例可以作为多个Thread的target,这样可以实现资源的共享。

       缺点:相对于继承Thread类,实现Runnable接口代码要繁琐一些

       代码实例如下:

[java]  view plain  copy
 print ?
  1. public class ImplementsRunnable implements Runnable{  
  2.       
  3.     @Override  
  4.     public void run() {  
  5.         System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());  
  6.     }  
  7.       
  8.     public static void main(String[] args) {  
  9.         // TODO Auto-generated method stub  
  10.         // 输出主线程的相关信息  
  11.         System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());   
  12.           
  13.         // 创建thread1线程  
  14.         ImplementsRunnable runnableTarget = new ImplementsRunnable();  
  15.         Thread thread1 = new Thread(runnableTarget,"ThreadName1");  
  16.         thread1.start();  
  17.           
  18.         // 以匿名内部类的形式创建target   创建thread2线程  
  19.         new Thread(new Runnable() {  
  20.             public void run() {  
  21.                 System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());   
  22.             }  
  23.         },"ThreadName2").start();  
  24.     }  
  25.   
  26. }  
[java]  view plain  copy
 print ?
  1. 输出结果:main ThreadId: 1  
  2.           ThreadName1 ThreadId: 9  
  3.           ThreadName2 ThreadId: 10  


(二)  继承Thread 类,重载Thread类的run()方法。事实上Thread类也是实现了Runnable接口。

       优点:代码相对其他两种方式更简洁

       缺点:由于java的继承机制是单一继承,继承Thread类就不能继承其他的类。

       代码实例:

[java]  view plain  copy
 print ?
  1. public class ExtendsThread extends Thread{  
  2.       
  3.     public ExtendsThread(String threadName) {  
  4.         super(threadName);  
  5.     }  
  6.   
  7.     public void run() {  
  8.         System.out.println("ThreadName: " + getName());  
  9.     }  
  10.       
  11.     public static void main(String[] args) {  
  12.         // TODO Auto-generated method stub  
  13.           
  14.         // 输出主线程的相关信息  
  15.         System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());   
  16.           
  17.         // 创建子线程  
  18.         ExtendsThread et = new ExtendsThread("childThread");  
  19.         et.start();  
  20.   
  21.     }  
  22. }  


(三)  实现Callable<V>接口 并实现接口的唯一方法call()

有些场景会希望得到线程的计算结果,这时可以实现Callable<V> 接口。Callable<V>接口和Runnable接口都是封装了一个异步任务,不同的是

Callable<V>接口具有返回值。同时Call<V>接口还是一个参数化的类型,这个参数就是线程的返回参数类型,比如线程若返回整型则Callable<Integer>

,若返回字符类型则为Callable<Object>。


通过实现Callable<V>接口创建线程,需要用到一个包装器FutureTask<V>,这个包装器同时实现了Runnable和Future<V>接口,它可以将Callable<V>

对象转换为Runnable和Future。

[java]  view plain  copy
 print ?
  1. public interface Callable<V> {  
  2.   
  3.         V call() throws Exception;  
  4.    }  
  5.       
  6.     public interface Future<V> {  
  7.   
  8.         boolean cancel(boolean mayInterruptIfRunning);  
  9.   
  10.         boolean isCancelled();  
  11.   
  12.         boolean isDone();  
  13.   
  14.         V get() throws InterruptedException, ExecutionException;  
  15.   
  16.         V get(long timeout, TimeUnit unit)  
  17.             throws InterruptedException, ExecutionException, TimeoutException;  
  18.     }  
  19.   
  20.     public interface RunnableFuture<V> extends Runnable, Future<V> {  
  21.         /** 
  22.          * Sets this Future to the result of its computation 
  23.          * unless it has been cancelled. 
  24.          */  
  25.         void run();  
  26.     }  
  27.       
  28.       
  29.     public class FutureTask<V> implements RunnableFuture<V> {  
  30.     ......  
  31.     }  

代码实例:

[java]  view plain  copy
 print ?
  1. public class ImplemetsCallable implements Callable<Integer>{  
  2.       
  3.     // 实现call()方法  
  4.     public Integer call() {  
  5.         return  35;  
  6.     }  
  7.   
  8.     public static void main(String [] args) throws   
  9.     InterruptedException, ExecutionException, TimeoutException {  
  10.           
  11.         ImplemetsCallable ic = new ImplemetsCallable();  
  12.         // 创建包装器 FutureTask 同时实现了Runnable和Future接口 可以将Callable 转换成Future和Runnable  
  13.         FutureTask<Integer> task = new FutureTask<Integer>(ic);  
  14.         Thread t = new Thread(task);  
  15.         t.start();  
  16.         //  调用FutureTask的get() 方法 获取线程的计算结果  
  17.         //  如果线程没有计算完结果 则get()方法会阻塞 直到线程计算完结果返回  
  18.         System.out.println(task.get());  
  19.           
  20.         //  get(long timeout, TimeUnit unit)方法在指定时间内获取线程计算结果,超时则抛出 TimeoutException异常  
  21.         //  如果运行计算结果的线程被中断则get()和get(long timeout, TimeUnit unit)方法都将抛出InterruptedException异常  
  22.         System.out.println(task.get(10000, TimeUnit.MILLISECONDS));  
  23.     }  
  24.   
  25. }  

以下代码是通过使用线程池的方式创建线程:

[java]  view plain  copy
 print ?
  1. public class TestCallable {  
  2.   
  3.     public static void main(String[] args) {  
  4.         // TODO Auto-generated method stub  
  5.         System.out.println("程序开始执行");  
  6.         List<Future> list = new ArrayList<Future>();  
  7.         int taskSize = 5;    
  8.         // 创建一个线程池    
  9.         ExecutorService pool = Executors.newFixedThreadPool(taskSize);   
  10.           
  11.         for (int i = 0; i<taskSize; i++) {  
  12.             MyCallable mc = new MyCallable("i "+i);  
  13.             Future f = pool.submit(mc);  
  14.             list.add(f);  
  15.         }  
  16.           
  17.         for (Future f : list) {  
  18.             try {  
  19.                 System.out.println(f.get().toString());  
  20.             } catch (InterruptedException e) {  
  21.                 // TODO Auto-generated catch block  
  22.                 e.printStackTrace();  
  23.             } catch (ExecutionException e) {  
  24.                 // TODO Auto-generated catch block  
  25.                 e.printStackTrace();  
  26.             }  
  27.         }  
  28.     }  
  29.   
  30. }  
  31.   
  32. class MyCallable implements Callable<Object> {  
  33.       
  34.     private String name;  
  35.       
  36.     public MyCallable(String name) {  
  37.         this.name = name;  
  38.     }  
  39.       
  40.     public Object call() {  
  41.         System.out.println("任务开始执行>>>>");  
  42.         long beginTime = System.currentTimeMillis();  
  43.         try {  
  44.             Thread.sleep(1000);  
  45.         } catch (InterruptedException e) {  
  46.             // TODO Auto-generated catch block  
  47.             e.printStackTrace();  
  48.         }  
  49.         long endTime = System.currentTimeMillis();  
  50.         long durTime = endTime - beginTime;  
  51.         System.out.println("任务执行完毕>>>>");  
  52.         return name + "任务执行完毕>>>> 总耗时: "+ durTime;  
  53.     }  
  54. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值