Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it not possible to supply a thread facory or name pattern to ForkJoinPool?

I would like to set name for threads of the ForkJoinPool used by work stealing pool, supplied by

ExecutorService newWorkStealingPool(int parallelism)

or

ExecutorService newWorkStealingPool()

So far I could not find a way to set custom names on threads used by this ExecutorService, is there a way?

newWorkStealingPool() basically supplies a ForkJoinPool, but ForkJoinPool also doesn't have a public constructor with supplied name pattern.

update: I have now found this constructor of ForkJoinPool which takes a thread factory ForkJoinPool.ForkJoinWorkerThreadFactory. But factory should return a ForkJoinWorkerThread, which doesn't have a public constructor. So I guess I will have to subclass ForkJoinWorkerThread.

like image 796
cpz Avatar asked Dec 16 '15 02:12

cpz


People also ask

How do you make a ForkJoinPool?

Creating a ForkJoinPoolYou create a ForkJoinPool using its constructor. As a parameter to the ForkJoinPool constructor you pass the indicated level of parallelism you desire. The parallelism level indicates how many threads or CPUs you want to work concurrently on on tasks passed to the ForkJoinPool .

How many threads are created in ForkJoinPool?

Its implementation restricts the maximum number of running threads to 32767 and attempting to create pools with greater than this size will result to IllegalArgumentException .

In which of the following ways we can submit a task to the ForkJoinPool?

There are three different ways of submitting a task to the ForkJoinPool . execute() – Desired asynchronous execution; call its fork method to split the work between multiple threads. invoke() – Await to obtain the result; call the invoke method on the pool.

How does ForkJoinPool work in Java?

ForkJoinPool acts recursively, unlike Executor threads, which splits the task and submits smaller chunks to worker Threads. ForkJoinPool takes a big task, splits it into smaller tasks, and those smaller tasks split themselves again into subtasks until each subtask is atomic or not divisible. So it works recursively.


2 Answers

This seems to be the minimum required code, reusing the existing default factory:

final ForkJoinWorkerThreadFactory factory = new ForkJoinWorkerThreadFactory()
{
    @Override           
    public ForkJoinWorkerThread newThread(ForkJoinPool pool)
    {
        final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
        worker.setName("my-thread-prefix-name-" + worker.getPoolIndex());
        return worker;
    }
};

forkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), factory, null, false); 
like image 118
Morten Haraldsen Avatar answered Sep 29 '22 17:09

Morten Haraldsen


(Answering your update)

The following should allow you full control over the threads produced by your ForkJoinPools. In my case I wanted to be able to do "dangerous" stuff like access system properties. The default implementation uses java.util.concurrent.ForkJoinWorkerThread.InnocuousForkJoinWorkerThread which has a security manager and zero permissions.

public class MyForkJoinThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory {
  @Override
  public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
    return new NotSoInnocuousWorkerThread(pool);
  }
}

and the worker thread (that now has all the same permissions as the rest of your application is this like this, plus whatever else you wanted....

public class NotSoInnocuousWorkerThread extends ForkJoinWorkerThread {
  protected NotSoInnocuousWorkerThread(ForkJoinPool pool) {
    super(pool);
  }
}

And you need to either pass the following property or set it in your code like this:

System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory", 
                   MyForkJoinThreadFactory.class.getName());
like image 38
Gus Avatar answered Sep 29 '22 16:09

Gus