Java多线程③——Guava并发

Guava的ListenableFuture是对多线程使用的一个很好的补充,通过ListenableFuture的addCallback我们可以很好的完成调用成功(onSuccess)或者失败(onFailure)以后的逻辑处理,使用方法如下:

@Slf4j
public class ListenableFutureDemo implements Callable{

    String info;

    public ListenableFutureDemo(String info) {
        this.info = info;
    }

    public static void main(String[] args) {
        log.info("----起床干活----");
        ExecutorService pool = Executors.newFixedThreadPool(10);
        //包装成Listenable的线程池
        ListeningExecutorService executorService = MoreExecutors.listeningDecorator(pool);
        ListenableFuture future1 = executorService.submit(new ListenableFutureDemo("昨夜西风凋碧树"));
        ListenableFuture future2 = executorService.submit(new ListenableFutureDemo("独上高楼"));

        Futures.addCallback(future1, new CallBackDemo(), MoreExecutors.directExecutor());
        Futures.addCallback(future2, new CallBackDemo(), pool);
        log.info("----结束干活----");
    }

    @Override
    public String call() throws Exception {
        return info;
    }
}

@Slf4j
class CallBackDemo implements FutureCallback {

    @Override
    public void onSuccess(@NullableDecl String o) {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("------{}-------", o);
    }

    @Override
    public void onFailure(Throwable throwable) {
        log.info("----难以置信的报错----------");
    }
}

 

以下是对常用类的介绍:

MoreExecutors:该类是final类型的工具类,提供了很多静态方法。比如ListeningDecorator方法将java线程池装饰为ListeningExecutorService,使用此实例submit方法即可初始化ListenableFuture对象。

ListeningExecutorService:该类是对ExecutorService的扩展,重新ExecutorService类中的submit方法,返回ListenableFuture对象。

ListenableFuture:该接口扩展了Future接口,增加了addListener方法,该方法在给定的executor上注册一个监听器,当计算完成时会马上调用该监听器。不能够确保监听器执行的顺序,但可以在计算完成时确保马上被调用。addListener和addCallback本质是一样的,addCallback是在addListener的基础上做了封装。

FutureCallback:该接口提供了OnSuccess和OnFailure方法。获取异步计算的结果并回调。

Futures:该类提供了很多实用的静态方法以供实用。

 

ListenableFutureTask:该类扩展了FutureTask类并实现了ListenableFuture接口,增加了addListener方法。

///将一个 ExecutorService 转换为 ListeningExecutorService,MoreExecutors装饰
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
//Guava提供两个callBack用于ListenableFuture回调,高版本已经去掉第二个方法
Futures.addCallback(ListenableFuture future, FutureCallback callback, Executor executor);
Futures.addCallback(ListenableFuture future, FutureCallback callback);
// 但是你可以继续设置当前线程
MoreExecutors.directExecutor()

Futures和其他相关方法罗列

 

@Slf4j
public class GuavaDemo implements Callable {

    static ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));

    public static void main(String[] args) {
        // ThreadFactoryBuilder 方便的threadFactory---
        //ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("测试").build();
        testSettableFuture(); //规定时间拿到结果;适合需要在规定时间拿结果的应用
    }

    public static void testFutures(){
        /**
         *  Futures相关
         **/
        //Futures.transform:对于ListenableFuture的返回值进行转换。
        //allAsList:对多个ListenableFuture的合并,返回一个当所有Future成功时返回多个Future返回值组成的List对象。注:当其中一个Future失败或者取消的时候,将会进入失败或者取消。
        //successfulAsList:和allAsList相似,唯一差别是对于失败或取消的Future返回值用null代替。不会进入失败或者取消流程。
        //immediateFuture/immediateCancelledFuture: 立即返回一个待返回值的ListenableFuture。
        //将ListenableFuture 转换成CheckedFuture。CheckedFuture 是一个ListenableFuture ,其中包含了多个版本的get 方法,方法声明抛出检查异常.这样使得创建一个在执行逻辑中可以抛出异常的Future更加容易
        //JdkFutureAdapters.listenInPoolThread(future): guava同时提供了将JDK Future转换为ListenableFuture的接口函数。
    }

    // SettableFuture 规定时间拿到结果;适合需要在规定时间拿结果的应用
    public static void testSettableFuture(){
        SettableFuture settableFuture = SettableFuture.create();
        executorService.submit(new Callable() {
            @Override
            public String call() throws Exception {
                TimeUnit.SECONDS.sleep(5);
                settableFuture.set("得到世界");
                log.info("会继续走下去么??");
                return "测试";
            }
        });
        try {
            log.info("-----" + settableFuture.get(2, TimeUnit.SECONDS));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String call() throws Exception {
        TimeUnit.SECONDS.sleep(2);
        return "测试";
    }
@Slf4j
public class FuturesMethodDemo {

    public static List createTickets() {
        List list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            list.add("车票" + i);
        }
        return list;
    }

    public static void main(String[] args) {
        List list = createTickets();//获取车票
        List> futures = Lists.newArrayList();
        ExecutorService pool = Executors.newFixedThreadPool(10);//定义线程数
        ListeningExecutorService executorService = MoreExecutors.listeningDecorator(pool);
        for (int i = 0; i < list.size(); i++) {
            futures.add(executorService.submit(new Task(list.get(i))));
        }
        /**   successfulAsList和allAsList  **/
        ListenableFuture> resultsFuture = Futures.successfulAsList(futures);
        //ListenableFuture> resultsFuture = Futures.allAsList(futures);
//        try {
//            //所有都执行完毕
//            List integers = resultsFuture.get();
//            log.info("结果:" + integers.stream().map(i -> i + "").collect(Collectors.joining(",")));
//        } catch (Exception e) {
//            log.error("出错了", e);
//        } finally {
//            log.info("操作完毕");
//            pool.shutdown();
//        }

        /** AsyncFunction和  immediateFuture **/
        ListenableFuture transformAsync = Futures.transformAsync(resultsFuture, new AsyncFunction, String>() {
            @Override
            public ListenableFuture apply(@NullableDecl List result) throws Exception {
                return Futures.immediateFuture(result.stream().map(i -> i + "").collect(Collectors.joining(",")));
            }
        }, pool);

        try {
            log.info("转换后的结果{}", transformAsync.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

 

 

 

 

 

 

 

 

你可能感兴趣的:(多线程,java多线程和并发)