1 带回调的线程池任务
Callable接口和Runable接口最大的区别是Callable可以拥有返回值,并可以通过回调的方式获取。同时通过Future的get方法,可以同步的获取到返回值,并保证任务已经完成
package com.cweeyii.threadpool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
* Created by wenyi on 16/10/16.
* Email:caowenyi@meituan.com
*/
public class CallableThreadPool {
private static final Logger LOGGER = LoggerFactory.getLogger(CallableThreadPool.class);
public static void main(String[] args) throws InterruptedException, ExecutionException {
int threadSize = 2;
ExecutorService executorService = Executors.newFixedThreadPool(threadSize);
List<Future<CallerHandle>> futureList=new ArrayList<>();
for (int i = 0; i < threadSize * 2; i++) {
CallableWorker worker = new CallableWorker();
Future<CallerHandle> future = executorService.submit(worker);
futureList.add(future);
}
executorService.shutdown();
for(Future<CallerHandle> future:futureList){
CallerHandle callerHandle=future.get();
LOGGER.info("{} 已经完成任务",callerHandle.getThreadName());
}
LOGGER.info("线程池关闭成功");
}
}
14:26:37.574 INFO (CallableWorker.java:20) - pool-1-thread-1 结束任务
14:26:37.575 INFO (CallableWorker.java:20) - pool-1-thread-2 结束任务
14:26:37.579 INFO (CallableThreadPool.java:29) - pool-1-thread-1 已经完成任务
14:26:37.582 INFO (CallableThreadPool.java:29) - pool-1-thread-2 已经完成任务
14:26:39.583 INFO (CallableWorker.java:20) - pool-1-thread-1 结束任务
14:26:39.583 INFO (CallableWorker.java:20) - pool-1-thread-2 结束任务
14:26:39.583 INFO (CallableThreadPool.java:29) - pool-1-thread-1 已经完成任务
14:26:39.584 INFO (CallableThreadPool.java:29) - pool-1-thread-2 已经完成任务
14:26:39.584 INFO (CallableThreadPool.java:32) - 线程池关闭成功
ps:注意必须调用线程池的shutdown方法,否则JVM虚拟机不会结束。同理子线程如果为非守护线程,JVM也必须等待所有线程结束后才能结束。
示例1:菲守护线程
package com.cweeyii.threadpool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Created by wenyi on 16/10/16.
* Email:caowenyi@meituan.com
*/
public class MainExit {
private static final Logger LOGGER = LoggerFactory.getLogger(MainExit.class);
public static void main(String[] args) {
new Thread(new SleepWorker()).start();
new Thread(new SleepWorker()).start();
LOGGER.info("主线程main已经完成={}",Thread.currentThread().getName());
}
}
15:57:06.639 INFO (MainExit.java:16) - 主线程main已经完成=main
15:57:08.641 INFO (SleepWorker.java:31) - threadName=Thread-1 线程结束null工作
15:57:08.641 INFO (SleepWorker.java:31) - threadName=Thread-0 线程结束null工作
示例2:守护线程
public class MainExit {
private static final Logger LOGGER = LoggerFactory.getLogger(MainExit.class);
public static void main(String[] args) {
Thread thread1=new Thread(new SleepWorker());
Thread thread2=new Thread(new SleepWorker());
thread1.setDaemon(true);
thread2.setDaemon(true);
LOGGER.info("主线程main已经完成={}",Thread.currentThread().getName());
}
}
15:58:00.128 INFO (MainExit.java:18) - 主线程main已经完成=main