Is java ExecutorService newSingleThreadExecutor performs all the tasks using only one Thread?

╄→尐↘猪︶ㄣ 提交于 2020-05-24 05:24:49

问题


I know that a java thread cannot be restarted. So when I submit more than one tasks to newSingleThreadExecutor, then how does it perform all tasks using single thread?

My understanding is that newSingleThreadExecutor will use maximum one thread at a time to process any submitted tasks. I guess same for newFixedThreadPool. If a Thread cannot be restarted then for performing n tasks, n threads should be spawned. I think newSingleThreadExecutor, newFixedThreadPool will make sure that not many threads should be spawned at a same time, like we do without using ExecutorService (where we attach each task with a thread and start separately)

Here is code example

class Task implements Runnable {
    public void run() {
        System.out.println("ThreadID-" + Thread.currentThread().getId());
        try {
            Thread.sleep(100);
        }
        catch (InterruptedException e) {
        }
    }
}

public class SingleThreadExecutorTest {
    public static void main(String[] args) {
        System.out.println("ThreadID-" + Thread.currentThread().getId());
        ExecutorService ex = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            ex.execute(new Task());
        }
    }
}

The above code always prints the same ThreadID.

If I replace below line

Executors.newSingleThreadExecutor();

with

ExecutorService ex = Executors.newFixedThreadPool(2);

Then again it is able to perform all tasks using 2 Threads.

Only when I use

Executors.newCachedThreadPool();

I see different Thread IDs.

How does ExecutorService reuse a Thread? Does it not let it reach to Dead State?


回答1:


The ThreadPoolExecutor maintains some Worker threads, which work like this:

public class Demo {

    public class Worker implements Runnable {
        @Override
        public void run() {
            Runnable task = getTaskFromQueue();
            while (task != null) {
                task.run();
                task = getTaskFromQueue();  // This might get blocked if the queue is empty, so the worker thread will not terminate
            }
        }
    }

    public static void main(String[] args) {
        Worker worker = new Worker();
        Thread thread = new Thread(worker);
        thread.start();
    }

}

When you submit a task to ThreadPoolExecutor which has a single Worker thread, the calling threads will put the task into a BlockingQueue on below condition:

  • the single Worker is busy
  • the BlockingQueue is not full

And when the Worker is free, it will retrieve new task from this BlockingQueue.



来源:https://stackoverflow.com/questions/49442966/is-java-executorservice-newsinglethreadexecutor-performs-all-the-tasks-using-onl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!