Since years ago (from Java 1.3/1.4) , JDK provides so many pattern for multiple thread / concurrency / parallelization, include:
- Tranditional new Thread()
- Future<>/Executors.newXXXThreadPool(), which support setRejectedExceptionHandler
- CompletableFuture
- ListenableFuture from Google Guava library (since the lib is depended by so many framework, I takes it as basic of java develop...)
- ForkJoinPool from Java 7
- Stream from Java 8
- new Thread(): Full but complicated control.
- Long lasting task, often start and finish together with the application process.
- Complicated exception handle.
- Weak coupling with other task.
- Give an common ThreadGroup, to group all thread you started in code into.
- Executors.newXXXThreadPool() and Future<>: Simple and quick
- Mostly used instance: Fixed/Cached thread pool
- Best performance for short, frequent tasks in same type, for example: async logger output.
- Define one pool instance for every category of task with a given ThreadGroup. Construct a common parent ThreadGroup (to me, use the ThreadGroup of "new Thread()") to all thread pools.
- CompletableFuture: Barely used by me, since ListenableFuture can do nearly everything it claimed.
- ListenableFuture: The coolest future it suppurted is Futures.successForList()!
- Futures.successForList(), which merge multiple futures into one, means I can control tasks universal! I use this feature for tasks spawning before Java 7/8 (ForjoinPool/Stream)
- It provide coupleing between tasks, but I found it useless in most scenario.
- ForkJoinPool:
- For short tasks, especially tasks family spawning from and converging back to one.
- Thread pool maintained by itself smartly.
- Not strictly, which mean some parallel defined by ForkJoinPool maybe run sequentially for reason of parallelism definied (by JVM "smartly" or by coder).
- Stream:
- For data flow processing
- Lazy!!!! Which provide possibility of larg throughput for big data processing.
- Spawn all sub-tasks in ForkJoinPool
- Default, use ForkJoinPool.commonPool()
- Can be hacked by: pool.submie(()->stream.runSomeTaskIncludeMapOrCollect())
- Drawback: It's a pattern of Map-Reduce, but no implementation of lazy dividing of task. Thus Divide/Conquer Mechanism can work fully by it!
- At last, I resolve the problem of "lazy splitting/dividing/partition of stream" by Spliterator.
没有评论:
发表评论