Java多线程之ThreadPool

这里演示了普通线程池以及带有返回值的线程池的使用方式

  1. package com.jadyer.thread.pool;  
  2.   
  3. import java.util.Random;  
  4. import java.util.concurrent.Callable;  
  5. import java.util.concurrent.CompletionService;  
  6. import java.util.concurrent.ExecutionException;  
  7. import java.util.concurrent.ExecutorCompletionService;  
  8. import java.util.concurrent.ExecutorService;  
  9. import java.util.concurrent.Executors;  
  10. import java.util.concurrent.Future;  
  11. import java.util.concurrent.TimeUnit;  
  12.   
  13. /** 
  14.  * ThreadPool Test 
  15.  * @see ================================================================================================ 
  16.  * @see 线程与进程的区别 
  17.  * @see 1)多个进程的内部数据和状态是完全独立的,而多线程则会共享一块内存空间和一组系统资源,有可能互相影响 
  18.  * @see 2)线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈。所以线程的切换比进程切换的负担要小 
  19.  * @see ================================================================================================ 
  20.  * @see 线程的启动方式和消亡 
  21.  * @see 1)以Thread.start()启动时,JVM会以线程的方式运行它。start()首先会为线程的执行准备系统资源,然后才去调用run方法 
  22.  * @see 2)以Thread.run()启动时,JVM会以普通方法运行它。此时就不会存在线程所特有的交替执行的效果 
  23.  * @see 3)一个线程类的两个对象,同时以start()方式运行时,JVM仍会把它们当作两个线程类来执行 
  24.  * @see 4)终止线程时,绝对不能使用stop()方法,而应该让run()自然结束 
  25.  * @see ================================================================================================ 
  26.  * @author 宏宇 
  27.  * @create Feb 29, 2012 1:13:43 AM 
  28.  */  
  29. public class ThreadPoolTest {  
  30.     public static void main(String[] args) {  
  31.         new ThreadPoolTest().threadPoolTest();  
  32.         new ThreadPoolTest().threadPoolScheduledTest();  
  33.         new ThreadPoolTest().threadPoolCallbaleAndFutureSignTest();  
  34.         new ThreadPoolTest().threadPoolCallbaleAndFutureMoreTest();  
  35.     }  
  36.       
  37.     /** 
  38.      * 创建线程池的几种方式 
  39.      * @see Executors.newFixedThreadPool(3);     //创建固定大小的线程池 
  40.      * @see Executors.newCachedThreadPool();     //创建缓存线程池。它会根据实际请求的线程数量动态创建线程 
  41.      * @see Executors.newSingleThreadExecutor(); //创建单个线程池。它可以实现线程死掉后重新启动的效果,但实际启动的是"替补线程" 
  42.      */  
  43.     public void threadPoolTest(){  
  44.         //newSingleThreadExecutor()的好处就是,若池中的线程死了,它会把一个"替补的线程"扶上位,即它会保证池中始终有一个线程存在   
  45.         ExecutorService threadPool = Executors.newSingleThreadExecutor();  
  46.         for(int i=1; i<=10; i++) {  
  47.             final int task = i;  
  48.             threadPool.execute(new MyThread(task)); //注意execute()的返回值是void   
  49.         }  
  50.         System.out.println("all of 10 tasks have committed......");  
  51.           
  52.         //线程池中的任务均执行完毕后,关闭线程池   
  53.         threadPool.shutdown();  
  54.     }  
  55.       
  56.     /** 
  57.      * 线程池启动定时器 
  58.      * @see Executors.newScheduledThreadPool(3).schedule();            //创建并执行在给定延迟后启用的一次性操作 
  59.      * @see Executors.newScheduledThreadPool(3).scheduleAtFixedRate(); //首次启动后,以固定的频率自动执行操作 
  60.      * @see scheduleAtFixedRate()支持间隔重复任务的定时方式,但不直接支持绝对定时方式,我们需要转换为相对时间的方式,来执行 
  61.      */  
  62.     public void threadPoolScheduledTest(){  
  63.         //10秒后自动执行一次   
  64.         //Executors.newScheduledThreadPool(3).schedule(new MyScheduledThread(), 10, TimeUnit.SECONDS);   
  65.         //6秒后首次执行,之后每2秒均自动执行一次   
  66.         Executors.newScheduledThreadPool(3).scheduleAtFixedRate(new MyScheduledThread(), 62, TimeUnit.SECONDS);  
  67.     }  
  68.       
  69.     /** 
  70.      * 线程池返回一个任务的值 
  71.      * @see 注意:这里需使用java.util.concurrent.ExecutorService.submit()来提交,它会返回Future对象 
  72.      * @see 注意:Future取得的结果类型,与Callable返回的结果类型,必须一致。我们这里是通过泛型来实现的 
  73.      */  
  74.     public void threadPoolCallbaleAndFutureSignTest(){  
  75.         ExecutorService threadPool =  Executors.newSingleThreadExecutor();  
  76.         Future<String> future = threadPool.submit(  
  77.             new Callable<String>() {  
  78.                 @Override  
  79.                 public String call() throws Exception {  
  80.                     Thread.sleep(2000);  
  81.                     return "张起灵";  
  82.                 };  
  83.             }  
  84.         );  
  85.         System.out.println("等待结果");  
  86.         try {  
  87.             System.out.println("拿到结果:" + future.get()); //future.get(4, TimeUnit.SECONDS)   
  88.         } catch (InterruptedException e) {  
  89.             e.printStackTrace();  
  90.         } catch (ExecutionException e) {  
  91.             e.printStackTrace();  
  92.         }  
  93.     }  
  94.       
  95.     /** 
  96.      * 线程池返回多个任务的值 
  97.      * @see java.util.concurrent.CompletionService用于提交一组Callable任务 
  98.      * @see CompletionService.take()会返回已完成的一个Callable任务所对应的Future对象 
  99.      * @see 这就好比同时种植了几块菜地,然后等待收菜。收菜时,哪块菜熟了,就先去收哪块菜地的菜 
  100.      */  
  101.     public void threadPoolCallbaleAndFutureMoreTest(){  
  102.         ExecutorService threadPool =  Executors.newFixedThreadPool(5);  
  103.         CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool);  
  104.         for(int i=1; i<=5; i++){  
  105.             final int taskCode = i;  
  106.             completionService.submit(  
  107.                 new Callable<Integer>(){  
  108.                     @Override  
  109.                     public Integer call() throws Exception {  
  110.                         Thread.sleep(new Random().nextInt(5000));  
  111.                         return taskCode;  
  112.                     }  
  113.                 }  
  114.             );  
  115.         }  
  116.         for(int i=0; i<5; i++){  
  117.             try {  
  118.                 System.out.println(completionService.take().get());  
  119.             } catch (InterruptedException e) {  
  120.                 e.printStackTrace();  
  121.             } catch (ExecutionException e) {  
  122.                 e.printStackTrace();  
  123.             }  
  124.         }  
  125.     }  
  126. }  
  127.   
  128.   
  129. class MyThread implements Runnable{  
  130.     private Integer task;  
  131.     public MyThread(Integer task){  
  132.         this.task = task;  
  133.     }  
  134.     @Override  
  135.     public void run() {  
  136.         //这里不需要写成j,因为它和threadPoolTest()里面的for()循环中的i并不是同一个方法中的变量,故其不会冲突   
  137.         for(int i=1; i<=10; i++) {  
  138.             try {  
  139.                 Thread.sleep(20);  
  140.             } catch (InterruptedException e) {  
  141.                 e.printStackTrace();  
  142.             }  
  143.             System.out.println(Thread.currentThread().getName() + " is looping of " + i + " for  task of " + task);  
  144.         }  
  145.     }  
  146. }  
  147.   
  148.   
  149. class MyScheduledThread implements Runnable{  
  150.     @Override  
  151.     public void run() {  
  152.         System.out.println("bombing......");  
  153.     }  
  154. }  
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值