这里演示了普通线程池以及带有返回值的线程池的使用方式
- packagecom.jadyer.thread.pool;
- importjava.util.Random;
- importjava.util.concurrent.Callable;
- importjava.util.concurrent.CompletionService;
- importjava.util.concurrent.ExecutionException;
- importjava.util.concurrent.ExecutorCompletionService;
- importjava.util.concurrent.ExecutorService;
- importjava.util.concurrent.Executors;
- importjava.util.concurrent.Future;
- importjava.util.concurrent.TimeUnit;
- /**
- *ThreadPoolTest
- *@see================================================================================================
- *@see线程与进程的区别
- *@see1)多个进程的内部数据和状态是完全独立的,而多线程则会共享一块内存空间和一组系统资源,有可能互相影响
- *@see2)线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈。所以线程的切换比进程切换的负担要小
- *@see================================================================================================
- *@see线程的启动方式和消亡
- *@see1)以Thread.start()启动时,JVM会以线程的方式运行它。start()首先会为线程的执行准备系统资源,然后才去调用run方法
- *@see2)以Thread.run()启动时,JVM会以普通方法运行它。此时就不会存在线程所特有的交替执行的效果
- *@see3)一个线程类的两个对象,同时以start()方式运行时,JVM仍会把它们当作两个线程类来执行
- *@see4)终止线程时,绝对不能使用stop()方法,而应该让run()自然结束
- *@see================================================================================================
- *@author宏宇
- *@createFeb29,20121:13:43AM
- */
- publicclassThreadPoolTest{
- publicstaticvoidmain(String[]args){
- newThreadPoolTest().threadPoolTest();
- newThreadPoolTest().threadPoolScheduledTest();
- newThreadPoolTest().threadPoolCallbaleAndFutureSignTest();
- newThreadPoolTest().threadPoolCallbaleAndFutureMoreTest();
- }
- /**
- *创建线程池的几种方式
- *@seeExecutors.newFixedThreadPool(3);//创建固定大小的线程池
- *@seeExecutors.newCachedThreadPool();//创建缓存线程池。它会根据实际请求的线程数量动态创建线程
- *@seeExecutors.newSingleThreadExecutor();//创建单个线程池。它可以实现线程死掉后重新启动的效果,但实际启动的是"替补线程"
- */
- publicvoidthreadPoolTest(){
- //newSingleThreadExecutor()的好处就是,若池中的线程死了,它会把一个"替补的线程"扶上位,即它会保证池中始终有一个线程存在
- ExecutorServicethreadPool=Executors.newSingleThreadExecutor();
- for(inti=1;i<=10;i++){
- finalinttask=i;
- threadPool.execute(newMyThread(task));//注意execute()的返回值是void
- }
- System.out.println("allof10taskshavecommitted......");
- //线程池中的任务均执行完毕后,关闭线程池
- threadPool.shutdown();
- }
- /**
- *线程池启动定时器
- *@seeExecutors.newScheduledThreadPool(3).schedule();//创建并执行在给定延迟后启用的一次性操作
- *@seeExecutors.newScheduledThreadPool(3).scheduleAtFixedRate();//首次启动后,以固定的频率自动执行操作
- *@seescheduleAtFixedRate()支持间隔重复任务的定时方式,但不直接支持绝对定时方式,我们需要转换为相对时间的方式,来执行
- */
- publicvoidthreadPoolScheduledTest(){
- //10秒后自动执行一次
- //Executors.newScheduledThreadPool(3).schedule(newMyScheduledThread(),10,TimeUnit.SECONDS);
- //6秒后首次执行,之后每2秒均自动执行一次
- Executors.newScheduledThreadPool(3).scheduleAtFixedRate(newMyScheduledThread(),6,2,TimeUnit.SECONDS);
- }
- /**
- *线程池返回一个任务的值
- *@see注意:这里需使用java.util.concurrent.ExecutorService.submit()来提交,它会返回Future对象
- *@see注意:Future取得的结果类型,与Callable返回的结果类型,必须一致。我们这里是通过泛型来实现的
- */
- publicvoidthreadPoolCallbaleAndFutureSignTest(){
- ExecutorServicethreadPool=Executors.newSingleThreadExecutor();
- Future<String>future=threadPool.submit(
- newCallable<String>(){
- @Override
- publicStringcall()throwsException{
- Thread.sleep(2000);
- return"张起灵";
- };
- }
- );
- System.out.println("等待结果");
- try{
- System.out.println("拿到结果:"+future.get());//future.get(4,TimeUnit.SECONDS)
- }catch(InterruptedExceptione){
- e.printStackTrace();
- }catch(ExecutionExceptione){
- e.printStackTrace();
- }
- }
- /**
- *线程池返回多个任务的值
- *@seejava.util.concurrent.CompletionService用于提交一组Callable任务
- *@seeCompletionService.take()会返回已完成的一个Callable任务所对应的Future对象
- *@see这就好比同时种植了几块菜地,然后等待收菜。收菜时,哪块菜熟了,就先去收哪块菜地的菜
- */
- publicvoidthreadPoolCallbaleAndFutureMoreTest(){
- ExecutorServicethreadPool=Executors.newFixedThreadPool(5);
- CompletionService<Integer>completionService=newExecutorCompletionService<Integer>(threadPool);
- for(inti=1;i<=5;i++){
- finalinttaskCode=i;
- completionService.submit(
- newCallable<Integer>(){
- @Override
- publicIntegercall()throwsException{
- Thread.sleep(newRandom().nextInt(5000));
- returntaskCode;
- }
- }
- );
- }
- for(inti=0;i<5;i++){
- try{
- System.out.println(completionService.take().get());
- }catch(InterruptedExceptione){
- e.printStackTrace();
- }catch(ExecutionExceptione){
- e.printStackTrace();
- }
- }
- }
- }
- classMyThreadimplementsRunnable{
- privateIntegertask;
- publicMyThread(Integertask){
- this.task=task;
- }
- @Override
- publicvoidrun(){
- //这里不需要写成j,因为它和threadPoolTest()里面的for()循环中的i并不是同一个方法中的变量,故其不会冲突
- for(inti=1;i<=10;i++){
- try{
- Thread.sleep(20);
- }catch(InterruptedExceptione){
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName()+"isloopingof"+i+"fortaskof"+task);
- }
- }
- }
- classMyScheduledThreadimplementsRunnable{
- @Override
- publicvoidrun(){
- System.out.println("bombing......");
- }
- }