回复:re:remove corePoolSize in ForkJoinPool<init> and hope to improve FJP's algorithm

唐佳未(佳未) tjw378335 at alibaba-inc.com
Mon Feb 24 02:10:05 UTC 2025


All tasks are submitted by the platform thread (main). 
```
ThreadFactory factory = Thread.ofVirtual().factory();
ExecutorService es = Executors.newThreadPerTaskExecutor(factory);
for(int i = 0 ; i < 5000; i++) {
System.out.println("execute: " + i);
es.execute(new Task(i));
}
es.shutdown();
try {
while(!es.awaitTermination(10, TimeUnit.SECONDS)) {
System.out.println("still waiting...");
 }
} catch (Exception e) {
e.printStackTrace();
}
class Task implements Runnable {
long start, run_start, end;
int num;
Task(int i) {
start = System.nanoTime();
num = i;
 }
 @Override
public void run() {
run_start = System.nanoTime();
Integer[] largeInt = new Integer[100];
for(int j = 0 ; j < largeInt.length; j++) {
largeInt[j] = j * 100;
 }
try {
Thread.sleep(100); // yield this vthread
 } catch (Exception e) {
e.printStackTrace();
 }
int sum = 0;
for(int j = 0 ; j < largeInt.length; j++) {
sum += largeInt[j];
 }
end = System.nanoTime();
double passTime = (end - run_start)/1000000.0;
double waitRunTime = (run_start - start)/1000000.0;
double totalTime = (end - start)/1000000.0;
System.out.println(Thread.currentThread() + "\t" + num + "-calc-result:" + sum + "\trun(ms): " + passTime+ "\twait-run(ms): " + waitRunTime + "\ttotal(ms): " + totalTime);
TestFJPParam.vtTimes[num] = passTime;
TestFJPParam.vtWaitTimes[num] = waitRunTime;
TestFJPParam.vtWholeTimes[num] = totalTime;
 }
 }
```
"ThreadPoolExecutor and SynchronousQueue" I mentioned before is not used in test. It just a idea. If we emulate this approach to add worker threads to complete tasks, would it be possible to reduce latency? 
------------------------------------------------------------------
发件人:Alan Bateman <alan.bateman at oracle.com>
发送时间:2025年2月20日(星期四) 18:27
收件人:"唐佳未(佳未)"<tjw378335 at alibaba-inc.com>; "loom-dev"<loom-dev at openjdk.org>
主 题:Re: re:remove corePoolSize in ForkJoinPool<init> and hope to improve FJP's algorithm
On 20/02/2025 01:40, 唐佳未(佳未) wrote:
:
java.util.concurrent.ForkJoinPool at 678ad349[Running, parallelism = 8, size = 8, active = 7, running = 0, steals = 3931, tasks = 0, submissions = 1426] java.util.concurrent.ForkJoinPool at 678ad349[Running, parallelism = 8, size = 8, active = 8, running = 0, steals = 5908, tasks = 0, submissions = 48] java.util.concurrent.ForkJoinPool at 678ad349[Running, parallelism = 8, size = 8, active = 8, running = 0, steals = 7731, tasks = 0, submissions = 236]
java.util.concurrent.ForkJoinPool at 678ad349[Running, parallelism = 8, size = 8, active = 2, running = 0, steals = 10370, tasks = 0, submissions = 0]
 Thanks for the jcmd output. It shows that there are no queued tasks in the worker queues (tasks = 0) but many tasks are in the external submission queues. Tasks for virtual threads are pushed to an external submission queue when a virtual thread is initially started, unparked by a platform thread, unblocked by another thread exiting a monitor that the virtual thread was blocked on, or awoken after sleep/timed-park.
 Your first mail speaks of a usage wth ThreadPoolExecutor and SynchronousQueue so I will guess there is some hand off from a platform thread to a virtual thread that would result in the task for the virtual thread being pushed to an external queue.
 Can you tell us a bit about the "run function"? I can't tell from the mails so far if this function is mostly compute bound or whether these virtual threads are blocking regularly to allow carriers be released to do other work. One of the mails mentions "tasks switched out but I wasn't sure how to read that. Even without this then you are correct that the scheduling is not fair.
 -Alan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20250224/4f90952a/attachment-0001.htm>


More information about the loom-dev mailing list