1) Difference between Callable and Runnable
The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.
2) ExecutorService Intro
"Executors are Java 5 name for the concept of thread pools. The 'Executor' naming is due to the fact that there is no guarantee that underlying implementation is actually a pool; an executor may be single-threaded or even synchronous".(From Spring Offical Doc)
Example:
package edu.xmu.thread; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class ExecutorTest { public static void main(String[] args) { List<CalculationCallable> subThreadList = initSubThreadList(); List<Future<Integer>> futures = new ArrayList<Future<Integer>>(); ExecutorService pool = Executors.newFixedThreadPool(5); System.out.println("Start submit callable. Timestamp: " + System.currentTimeMillis()); for (CalculationCallable calThread : subThreadList) { futures.add(pool.submit(calThread)); } System.out .println("Finished submit callable. Start getFutures. Timestamp: " + System.currentTimeMillis()); int sum = 0; for (Future<Integer> future : futures) { try { sum += future.get(); } catch (Exception e) { e.printStackTrace(); } } System.out.println("Finished getFutures. sum: " + sum + ", Timestamp: " + System.currentTimeMillis()); pool.shutdown(); } private static List<CalculationCallable> initSubThreadList() { CalculationCallable thread1 = new CalculationCallable(Arrays.asList( 200, 200, 200, 200)); CalculationCallable thread2 = new CalculationCallable(Arrays.asList( 300, 300, 300, 300)); CalculationCallable thread3 = new CalculationCallable(Arrays.asList( 300, 300, 300, 300)); CalculationCallable thread4 = new CalculationCallable(Arrays.asList( 300, 300, 300, 300)); CalculationCallable thread5 = new CalculationCallable(Arrays.asList( 300, 300, 300, 300)); List<CalculationCallable> subThreadList = new ArrayList<CalculationCallable>(); subThreadList.add(thread1); subThreadList.add(thread2); subThreadList.add(thread3); subThreadList.add(thread4); subThreadList.add(thread5); return subThreadList; } } class CalculationCallable implements Callable<Integer> { private List<Integer> numList; public CalculationCallable(List<Integer> numList) { super(); this.numList = numList; } @Override public Integer call() throws Exception { int sum = 0; try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } for (int i : numList) { sum += i; } return sum; } }
Output:
Start submit callable. Timestamp: 1400053633686 Finished submit callable. Start getFutures. Timestamp: 1400053633687 Finished getFutures. sum: 5600, Timestamp: 1400053635687 // We can see that submit(Callable) will not cause execution of Callable. // It just like a process of "register". // And future.get() will start the execution process instead. // And future.get() will start all the callables in the ExecutiveService(Pool)
Attention:
1> There is a disadvantage: If the first task takes a long time to compute and all the other tasks end before the first, the current thread cannot compute sum before the first task ends.
2> Java has the solution for this, CompletionService.
Extensions:
public static void main(String[] args) throws InterruptedException { List<CalculationCallable> subThreadList = initSubThreadList(); ExecutorService pool = Executors.newFixedThreadPool(5); System.out.println("Start submit callable. Timestamp: " + System.currentTimeMillis()); List<Future<Integer>> futures = pool.invokeAll(subThreadList); System.out .println("Finished submit callable. Start getFutures. Timestamp: " + System.currentTimeMillis()); int sum = 0; for (Future<Integer> future : futures) { try { sum += future.get(); } catch (Exception e) { e.printStackTrace(); } } System.out.println("Finished getFutures. sum: " + sum + ", Timestamp: " + System.currentTimeMillis()); pool.shutdown(); }
Output:
Start submit callable. Timestamp: 1400661124891 Finished submit callable. Start getFutures. Timestamp: 1400661126892 Finished getFutures. sum: 5600, Timestamp: 1400661126892 // We will notice that invokeAll(Collection<?>..) will start the execution of all threads // Instead of future.get(), we now bring the execution time forward.
The source code snippet for invokeAll(Collection<? extends Callable<T>>)
for (Future<T> f : futures) { if (!f.isDone()) { try { f.get(); } catch (CancellationException ignore) { } catch (ExecutionException ignore) { } } }
3) CompletionService Intro
Example:
public static void main(String[] args) { List<CalculationCallable> subThreadList = initSubThreadList(); ExecutorService threadPool = Executors.newFixedThreadPool(5); CompletionService<Integer> pool = new ExecutorCompletionService<Integer>( threadPool); System.out.println("Start submit callable. Timestamp: " + System.currentTimeMillis()); for (CalculationCallable calThread : subThreadList) { pool.submit(calThread); } System.out .println("Finished submit callable. Start getFutures. Timestamp: " + System.currentTimeMillis()); int sum = 0; for (int i = 0; i < 5; i++) { try { sum += pool.take().get(); } catch (Exception e) { e.printStackTrace(); } } System.out.println("Finished getFutures. sum: " + sum + ", Timestamp: " + System.currentTimeMillis()); threadPool.shutdown(); }
Output:
Start submit callable. Timestamp: 1400054835960 Finished submit callable. Start getFutures. Timestamp: 1400054835961 Finished getFutures. sum: 5600, Timestamp: 1400054837961 // The CompletionService is based on ExecutorService to work. // With that, you have the result in the order they are completed and you don't have to keep a collection of Future.
Reference Links:
1) http://baptiste-wicht.com/posts/2010/09/java-concurrency-part-7-executors-and-thread-pools.html
2) http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html
相关推荐
C++11引入了并发编程的支持,包括`std::future`、`std::promise`以及`std::async`等工具,而`concurrency::task`是微软的PPL(Parallel Patterns Library,并行模式库)的一部分,为C++提供了更高级别的异步编程模型...
本教程"JavaConcurrency:Java并发教程"旨在深入探讨Java平台上的并发机制和最佳实践。 Java并发的核心概念包括线程、同步、互斥、死锁以及线程安全。在Java中,线程是并发执行的基本单元,通过创建Thread对象或者...
4. **并发工具类**:Java 5及更高版本引入了`java.util.concurrent`包,包含各种并发工具,如`ExecutorService`、`Future`、`Semaphore`、`CountDownLatch`和`CyclicBarrier`等。这些工具可以帮助开发者更有效地管理...
Java Concurrency in Practice 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者...
<<java并行编程>>英文版chm格式,英文名称<Java Concurrency in Practice>,一直想买这本书,但总是缺货,找到了电子版,分享给大家。 Java Concurrency in Practice By Brian Goetz, Tim Peierls, Joshua Bloch,...
Using the concurrency building blocks in java.util.concurrent Performance optimization dos and don'ts Testing concurrent programs Advanced topics such as atomic variables, nonblocking algorithms, ...
《并发的艺术》(The Art of Concurrency: A Thread Monkey's Guide to Writing Parallel Applications)是一本面向程序员的专业书籍,旨在深入讲解并发编程的核心概念和技术。本书由Clay Breshears撰写,并于2009年...
《Java并发编程实践》(Java Concurrency in Practice)是一本深度探讨Java多线程和并发编程的经典著作。这本书由Brian Goetz、Tim Peierls、Joshua Bloch、David Holmes和Doug Lea合著,旨在帮助Java开发者理解和解决...
《Java Concurrency in Practice》是Java并发编程领域的一本经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowles和Doug Lea等专家共同编写。这本书深入探讨了Java平台上的多线程和并发编程,旨在...
Get an easy introduction to reactive streams in Java to handle concurrency, data streams, and the propagation of change in today's applications. This compact book includes in-depth introductions to ...
Java Concurrency in practice
Java Concurrency in Practice JAVA并发编程实践中文版(全)第二部分
本项目"Java-Concurrency:Java并发学习演示"旨在提供一个深入理解Java并发机制的实践平台。以下是对相关知识点的详细说明: 1. **线程与进程**:在计算机系统中,进程是资源分配的基本单位,而线程是执行的基本单位...
java8 源码 并发操作合集 这是一个关于并发的系列。以实战为驱动,了解并发编程中的那些骚操作。文中的示例代码和部分解释来源于网络,你可以把这个系列当做一本工具书,想不起来的时候来看一看,顺便star一发也是...
这些API包括`java.util.concurrent`包中的`ExecutorService`、`Future`、`Semaphore`、`CyclicBarrier`、`CountDownLatch`等类,它们为线程管理和同步提供了强大的工具。 - `ExecutorService`是一个接口,它定义了...
Java并发包提供了`ExecutorService`和`ThreadPoolExecutor`,它们是线程池的实现。线程池允许我们预先创建一组线程,当有任务需要执行时,可以从池中获取空闲线程,而不是每次都需要创建新线程,这大大提高了效率并...
"java-concurrency:代码审查清单" 提供了一套用于确保代码在并发环境下的正确性和高效性的检查指南。以下是一些核心的并发编程知识点: 1. **线程安全**:线程安全是指一个类或方法在多线程环境中能够被正确地访问...
《Java Concurrency in Practice》是Java并发编程领域的一本经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、Joe Bowbeer、David Holmes和Doug Lea合著,国内有热心人士进行了中文翻译,使得更多的中国开发者...