Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Random;
- import java.util.concurrent.ForkJoinPool;
- import java.util.concurrent.ForkJoinTask;
- import java.util.concurrent.RecursiveAction;
- import java.util.concurrent.atomic.AtomicLong;
- /**
- * This is a small sample which mixes forked/joined task
- * with asynchronously forked parallel tasks.
- *
- * The sample work task calculates some random values
- * and increments a result counter just to waste some CPU.
- */
- public class FJStalled {
- /**
- * Execute given work, possibly split off some part of it.
- * @param work to do.
- */
- void doWork(int work) {
- // this causes the problem ...
- if(work>10)
- work -= submitParallelWork(5);
- // waste some CPU by calculating many random values
- Random r = new Random(result.get());
- double value = 0;
- for(int i=0; i<1000*work; i++)
- value += r.nextDouble();
- long increment = Math.round(value);
- // just to see some result
- result.addAndGet(increment);
- }
- // some asynchronously forked task
- volatile ForkJoinTask<?> parallel = null;
- /**
- * Try to fork some parallel chunk of work which is not joined.
- * @param chunk available
- * @return chunk being calculated asynchronously or 0
- */
- int submitParallelWork(int chunk) {
- // see if any other parallel work was done
- if((parallel==null || parallel.isDone())) {
- parallel = work(chunk).fork();
- return chunk;
- } else
- return 0;
- }
- /**
- * Perform some work and possibly split it into about 10 sub tasks.
- * @param work to do
- * @return a ForkJoinTask to execute the work.
- */
- RecursiveAction work(final int work) {
- return new RecursiveAction() {
- @Override
- protected void compute() {
- // split into smaller tasks
- if(work>100) {
- List<RecursiveAction> subtasks = new ArrayList<>(10);
- int todo = work;
- int chunk = work/10;
- while(todo>0) {
- int count = Math.min(todo, chunk);
- subtasks.add(work(count));
- todo -= count;
- }
- invokeAll(subtasks);
- } else {
- // execute directly
- doWork(work);
- }
- }
- };
- }
- // just a dummy value to be modified as a result ....
- final AtomicLong result = new AtomicLong(0);
- public static void main(String ... args) {
- final ForkJoinPool pool = new ForkJoinPool();
- FJStalled sample = new FJStalled();
- pool.invoke(sample.work(1000000));
- // wait for any parallel work submitted.
- if(sample.parallel!=null)
- sample.parallel.join();
- System.out.format("done: %d\n", sample.result.get());
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement