diff --git a/notes/Java 并发.md b/notes/Java 并发.md index eaef96f8..437cb6c1 100644 --- a/notes/Java 并发.md +++ b/notes/Java 并发.md @@ -927,11 +927,61 @@ public class ProducerConsumer { produce..produce..consume..consume..produce..consume..produce..consume..produce..consume.. ``` - ## ForkJoin -// TODO +主要用于并行计算中,和 MapReduce 原理类似,都是把大的计算任务拆分成多个小任务并行计算。 +```java +public class ForkJoinExample extends RecursiveTask { + private final int threhold = 5; + private int first; + private int last; + + public ForkJoinExample(int first, int last) { + this.first = first; + this.last = last; + } + + @Override + protected Integer compute() { + int result = 0; + if (last - first <= threhold) { + // 任务足够小则直接计算 + for (int i = first; i <= last; i++) { + result += i; + } + } else { + // 拆分成小任务 + int middle = first + (last - first) / 2; + ForkJoinExample leftTask = new ForkJoinExample(first, middle); + ForkJoinExample rightTask = new ForkJoinExample(middle + 1, last); + leftTask.fork(); + rightTask.fork(); + result = leftTask.join() + rightTask.join(); + } + return result; + } +} +``` + +```java +public static void main(String[] args) throws ExecutionException, InterruptedException { + ForkJoinExample example = new ForkJoinExample(1, 10000); + ForkJoinPool forkJoinPool = new ForkJoinPool(); + Future result = forkJoinPool.submit(example); + System.out.println(result.get()); +} +``` + +ForkJoin 使用 ForkJoinPool 来启动,它是一个特殊的线程池,线程数量取决于 CPU 核数。 + +```java +public class ForkJoinPool extends AbstractExecutorService +``` + +ForkJoinPool 实现了工作窃取算法来提高 CPU 的利用率。每个线程都维护了一个双端队列,用来存储需要执行的任务。工作窃取算法允许空闲的线程从其它线程的双端队列中窃取一个任务来执行。窃取的任务必须是最晚的任务,避免和队列所属线程发生竞争。例如下图中,Thread2 从 Thread1 的队列中拿出最晚的 Task1 任务,Thread1 会拿出 Task2 来执行,这样就避免发生竞争。但是如果队列中只有一个任务时还是会发生竞争。 + +

# 九、线程不安全示例 @@ -1593,3 +1643,5 @@ public static String concatString(String s1, String s2, String s3) { - [6장 Thread Synchronization](https://www.slideshare.net/novathinker/6-thread-synchronization) - [How is Java's ThreadLocal implemented under the hood?](https://stackoverflow.com/questions/1202444/how-is-javas-threadlocal-implemented-under-the-hood/15653015) - [Concurrent](https://sites.google.com/site/webdevelopart/21-compile/06-java/javase/concurrent?tmpl=%2Fsystem%2Fapp%2Ftemplates%2Fprint%2F&showPrintDialog=1) +- [JAVA FORK JOIN EXAMPLE](http://www.javacreed.com/java-fork-join-example/ "Java Fork Join Example") +- [聊聊并发(八)——Fork/Join 框架介绍](http://ifeve.com/talk-concurrency-forkjoin/) diff --git a/pics/15b45dc6-27aa-4519-9194-f4acfa2b077f.jpg b/pics/15b45dc6-27aa-4519-9194-f4acfa2b077f.jpg new file mode 100644 index 00000000..a61ab275 Binary files /dev/null and b/pics/15b45dc6-27aa-4519-9194-f4acfa2b077f.jpg differ