简体   繁体   中英

Time slicing algorithm in thread pools

First let's talk about raw threads. Say I have 4 cores and 6 threads. Those 4 cores would 'time-slice' those 6 threads. Giving some time of them all to those 4 cores.

But say I have fixed pool of 4 threads, where I run, say 10 threads. I read that it would 'view' those 10 threads as tasks. Meaning it won't time-slice 10 threads, but run 4 at once, and once one of them finishes, it would take another and so on.

I am a little confused, why in first case there is time slicing and in second case there is not? But technically there could be (say I have 4 cores and pool of 5 that work with those 10 threads).Then those 5 threads would be time sliced in those 4 cores. Also in 5 threads there could me max 5 tasks at the same time, until one finishes it can take next.

I wrote this with a lot of thinking. Did I say something wrong here? And can someone make a basic rule of thumb of how I can understand this instantly without overthinking? I feel like I am missing basics.

In the first case (4 cores and 6 threads), 4 threads would run at the same time. 2 threads will be waiting.
For instance, if threads 1, 2, 3, 4 are running and 5, 6 are waiting, then its possible that after some time, threads 1, 3, 5, 6 are running and 2, 4 are waiting.
This is what time-slicing means.

In the second case, when you have a thread pool of 4 worker threads, again the same thing will happen.
Suppose you submitted 10 tasks(Runnables), then 4 of those tasks would definitely run at once; 6 will be waiting in the threadpool queue.
Whenever a task is done, the thread will pull another task from the queue.
This will keep on happening until there are no more tasks left in the queue.
Note that even when there are no tasks in the queue, the 4 worker threads are still alive, although in sleeping state (OS will run threads from other processes).

This thread pool design is better if all the tasks are 100% CPU-bound because if the OS has only 4 cores, then having more than 4 threads is useless, no matter how many tasks are pending.
In general, its not efficient to have a lot of threads running in the same system, as context switching is expensive and slow.

I have fixed pool of 4 threads, where I run, say 10 threads.

Normally you don't submit Thread objects to an ExecutorService because it creates confusion like this.

Submitting a Thread object to an ExecutorService is only possible thanks to the fact that the Thread class implements Runnable . The ExecutorService will treat the Thread object the same as any other implementation of Runnable:

When you submit a Thread object to a thread pool, it's added to the pool's work queue . One the threads in the pool then picks it up, and calls the Thread.run() method directly, like it would for any other instance of Runnable.

The run() method of the Thread object therefore runs in one of the thread pool's threads, and not in a new thread of its own. The Thread.start() method is never called to start a new thread.

These two are equivalent:

threadPool.submit(new Thread() {
    public void run() {
        doSomething();
    }
});

threadPool.submit(new Runnable() {
    public void run() {
        doSomething();
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM