多线程-异步阻塞 异步非阻塞 Java

525 阅读3分钟
  1. 异步阻塞,等待任务完成。再继续后续操作

示例代码


public static void main(String[] args) {
    System.out.println("main");

    // 注意使用 ExecutorService 而非 Executor
    ExecutorService executorService = Executors.newFixedThreadPool(1);

    Future<String> future = executorService.submit(() -> {
        System.out.println( "pool-1-thread-1");

        try {
            Thread.sleep(30000);
        } catch (Exception e) {
            e.printStackTrace();

        }

        //此处为Callable接口实现
        // 业务代码
        System.out.println("执行异步任务...  查询字段配置ing");
        System.out.println(Thread.currentThread().getName()+"线程里面结束任务");
        return "返回执行结果 over";
    });
    System.out.println("main");

    try {
        //判断异步线程是否执行完成
        if (future.isDone()) {
            System.out.println("判断任务是否完成:线程执行完成");
        }

//# java接口超时设置_java接口请求超时处理方法
//String   r = future.get(10000 * 1,TimeUnit.MILLISECONDS);
//--结果如下--
//java.util.concurrent.TimeoutException
//	at java.util.concurrent.FutureTask.get(FutureTask.java:205)


        //获取异步线程的执行结果,若未完成将阻塞
        String result = future.get();
        System.out.println("执行结果 :" +result);

        if (future.isDone()) {
            System.out.println("返回结果 :  线程执行完成");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }


}
执行结果:

main
pool-1-thread-1
执行异步任务...  查询字段配置ing
pool-1-thread-1线程里面结束任务
执行结果 :返回执行结果 over
返回结果 :  线程执行完成


2. 异步非阻塞,直接继续后续操作


```js

/**
 * . 单例
 */
private static ProcessThreadPool bTaskThreadPool;

private final static Integer THREAD_POOL_SIZE = 48;

/**
 * 线程池.
 */
private ThreadPoolExecutor pool;

/**
 * 构造函数. 初始化线程池.
 * corePoolSize核心线程数大小 48
 * maximumPoolSize 最大线程数 1024
 * keepAliveTime  闲线程保持存活时间 60 s
 * workQueue 保存任务的阻塞队列 1024*4
 * handler 拒绝策略 CallerRunsPolicy
 * 既不抛弃任务也不抛出异常,直接主线程来执行此任务, 注:虽然提供了反馈控制机制,但是将降低新任务的提交速度
 *
 * @param threadPoolSize 线程池大小
 */
private ProcessThreadPool(int threadPoolSize) {
    // 初始化48个线程跑
    ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("thread-runner-%d").build();
    pool = new ThreadPoolExecutor(THREAD_POOL_SIZE, 1024,
            60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(1024 * 4)
            , namedThreadFactory);
    pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

}

/**
 * TODO 单例模式.
 *
 * @param threadPoolSize 线程池大小
 * @return 当前线程池的引用
 */
public static ProcessThreadPool getBTaskThreadPool(int threadPoolSize) {
    if (bTaskThreadPool == null) {
        synchronized (ProcessThreadPool.class) {
            if (bTaskThreadPool == null) {
                bTaskThreadPool = new ProcessThreadPool(THREAD_POOL_SIZE);
            }
        }
    }
    return bTaskThreadPool;
}

/**
 上层对任务分批, 加载任务,将任务加载到线程池任务队列中.
 *
 * @param task        加载的任务runnable
 * @param logBusiness 异常日志
 */
public void loadTasks(Runnable task, LogBusiness logBusiness) {
    try {
        // 加入任务
        pool.execute(task);
    } catch (Exception ex) {
        ex.printStackTrace();
        logBusiness.writeExceptionLog(new MLogException(ExceptionLevel.Error, "cl-bill-consumption", "将任务添加线程池异常", ex));
    }
}


ProcessThreadPool.getBTaskThreadPool(1).loadTasks(new AsyncQueryBusinessFieldConfigThread(corpNo, commonConfigService, applicationContext), logBusiness);



class AsyncQueryBusinessFieldConfigThread implements Runnable {

    private ApplicationContext applicationContext;
    private String corpNo;
    private CommonConfigServiceImpl commonConfigService;


    /**
     * 数据接口.
     */

    public AsyncQueryBusinessFieldConfigThread(String corpNo, CommonConfigServiceImpl commonConfigService, ApplicationContext applicationContext) {

        this.corpNo = corpNo;
        this.commonConfigService = commonConfigService;
        this.applicationContext = applicationContext;
    }

    @Override
    public void run() {
        List<String> dbData = queryBusinessFieldConfig(corpNo);
        if (CollectionUtils.isNotEmpty(dbData)) {
            //初始化缓存
            corpNeedUpdateModifyTimeFieldsCache.put(corpNo, dbData);
        }
    }

}

  1. 异步阻塞调用,多线程



Runnable runnable = new Runnable() {

    @Override
    public void run() {
        try {
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();

        }    System.out.println("执行Runnable任务...");

    }
};

Callable callable = new Callable() {

    @Override
    public Object call() {
        try {
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();

        }    System.out.println("执行Callable任务...");

        return "执行结果3";
    }
};


ExecutorService service = Executors.newFixedThreadPool(1);

//使用适配器模式,将Runnable转化为Callable引用
Callable<String> callable1 = Executors.callable(runnable, "执行结果1");
//内部也是使用的适配器
Future<String> future1 = service.submit(runnable, "执行结果2");

Future<String> future2 = service.submit(callable1);
Future<String> future3 = service.submit(callable);

try {
    System.out.println(future1.get());
    System.out.println(future2.get());
    System.out.println(future3.get());
} catch (InterruptedException | ExecutionException e) {
}

---------执行结果-----

执行Runnable任务... 执行结果2 执行Runnable任务... 执行结果1 执行Callable任务... 执行结果3