sumbit 之所以可以接收返回值,是因为参数中可以传递:Callable task,而通过 callable 创建的线程任务有返回值并且可以抛出异常。
/** * execute VS sumbin * execute 提交任务没有返回值 * submit 提交任务有返回值 */ @Test public void test3() throws ExecutionException, InterruptedException { ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 10, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<>(20)); // execute executor.execute(new Runnable() { @Override public void run() { System.out.println("Hello, execute"); } }); // submit 使用 Future<String> future = executor.submit(new Callable<String>() { @Override public String call() throws Exception { System.out.println("Hello, submit"); return "submit success"; } }); System.out.println(future.get()); }它们的另一个区别是 execute() 方法属于 Executor 接口的方法,而 submit() 方法则是属于 ExecutorService 接口的方法。
线程池的使用:
import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; /** * @author xiandongxie */ public class ThreadPool { //参数初始化 返回Java虚拟机可用的处理器数量 // private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int CPU_COUNT = 2; //核心线程数量大小 private static final int corePoolSize = Math.max(2, Math.min(CPU_COUNT - 1, 4)); //线程池最大容纳线程数 private static final int maximumPoolSize = CPU_COUNT * 2 + 1; //线程空闲后的存活时长 private static final int keepAliveTime = 30; //任务过多后,存储任务的一个阻塞队列 BlockingQueue<Runnable> workQueue = new SynchronousQueue<>(); //线程的创建工厂 ThreadFactory threadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); public Thread newThread(Runnable r) { return new Thread(r, "AdvacnedAsyncTask #" + mCount.getAndIncrement()); } }; //线程池任务满载后采取的任务拒绝策略: 不执行新任务,直接抛出异常,提示线程池已满 RejectedExecutionHandler rejectHandler = new ThreadPoolExecutor.AbortPolicy(); //线程池对象,创建线程 ThreadPoolExecutor mExecute = new ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, rejectHandler ); public static void main(String[] args) { System.out.println("main start ..... \nCPU_COUNT = " + CPU_COUNT + "\tcorePoolSize=" + corePoolSize + "\tmaximumPoolSize=" + maximumPoolSize); ThreadPool threadPool = new ThreadPool(); ThreadPoolExecutor execute = threadPool.mExecute; // 预启动所有核心线程 execute.prestartAllCoreThreads(); for (int i = 0; i < 5; i++) { execute.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "\tstart..." + System.currentTimeMillis()); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "\tend..." + System.currentTimeMillis()); } }); } execute.shutdown(); System.out.println("main end ....."); } }