[Java学习]Java线程池(Callable+Future模式)

tech2026-04-02  1

转载文章:https://www.cnblogs.com/myxcf/p/9959870.html Java通过Executors提供四种线程池 1).newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 2).newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 3).newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。 4).newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。 在多线程的开发中往往会遇到这种情况:主线程需要知道子线程的运行结果,以便确定如何执行任务.JDK1.5以后就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。 步骤: 1)任务类实现Callable接口 2)创建线程池:ExecutorService es = Executors.newCachedThreadPool(); 3)执行任务:ChuJu cj = new ChuJu();Future future = es.submit(cj); 4)获取子线程中任务的执行结果:future.get() 下面通过实例简单说下其用法: 场景:假如你想做饭,但是没有厨具,也没有食材。网上购买厨具比较方便,食材去超市买更放心,即买出具、买食材,这两个任务异步执行,买好后才能去做饭。

创建一个com.tencent.baosen.callable.LearnCallable测试类:

package com.tencent.baosen.callable; import java.util.concurrent.*; //买厨具的类,实现Callable接口 class ChuJu implements Callable<Boolean> { @Override public Boolean call() { try{ System.out.println("A开始去买厨具"); Thread.sleep(3000); System.out.println("A买好厨具回来了!"); }catch (InterruptedException e){ e.printStackTrace(); } return true; } } //买食材的类,实现Callable接口 class ShiCai implements Callable<Boolean>{ @Override public Boolean call() { try{ System.out.println("B开始去买食材"); Thread.sleep(2000); System.out.println("B买好食材回来了"); }catch(InterruptedException e){ e.printStackTrace(); } return true; } } //做饭的类,实现Callable接口 class ZuoFan implements Callable<Boolean>{ @Override public Boolean call() { try{ System.out.println("开始做饭"); Thread.sleep(5000); System.out.println("已做好饭,可以吃饭了。"); }catch (InterruptedException e){ e.printStackTrace(); } return true; } } public class LearnCallable { public static void main(String[] args) { ExecutorService es = Executors.newCachedThreadPool(); ChuJu cj = new ChuJu(); ShiCai sc = new ShiCai(); Future<Boolean> f1 = es.submit(cj); Future<Boolean> f2 = es.submit(sc); try{ Boolean b1 = f1.get();//会阻塞当前线程 Boolean b2 = f2.get(); System.out.println("A的事情是否做完了:"+b1); System.out.println("B的事情是否做完了:"+b2); if(b1 && b2){ ZuoFan zf = new ZuoFan(); es.submit(zf); } }catch(Exception e){ e.printStackTrace(); } es.shutdown(); } }

运行结果:

A开始去买厨具 B开始去买食材 B买好食材回来了 A买好厨具回来了! A的事情是否做完了:true B的事情是否做完了:true 开始做饭 已做好饭,可以吃饭了。

从运行结果可以看出,买出具代码和买食材代码是异步执行的,这两个都执行完毕后,才执行的做饭代码。那么为什么子线程zuofan没有先执行呢?由于Future的get()方法没有得到返回值,让当前线程暂时挂起了。 注意:Future的get()方法,如果拿不到结果会阻塞当前线程。

最新回复(0)