Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

i'm using java theadpool ,but i got a error i can't understand

Tags:

java

<bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="6"/>
    <property name="maxPoolSize" value="6"/>
    <property name="queueCapacity" value="5"/>
    <property name="keepAliveSeconds" value="120"/>
    <property name="threadNamePrefix" value="myThread_"/>
</bean>

    public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

    ThreadPoolTaskExecutor executor = (ThreadPoolTaskExecutor) context.getBean("threadPoolTaskExecutor");
    List<Integer> list = new ArrayList<Integer>();

    for(int i=0;i<1000;i++){
        list.add(i);
        if(6 == list.size()){
            doWork(list,executor);
            list.clear();
        }
    }

    if(list.size() > 0)
        doWork(list,executor);

    System.out.println("all work finished");

}

static void doWork(List<Integer> list,ThreadPoolTaskExecutor executor){
    final CountDownLatch latch = new CountDownLatch(list.size());
    for(final int i:list){
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(200);
                    latch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    try {
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

Above is my code. When I set queueCapacity 6 or larger than 6 it works well, but when queueCapacity is less than 6 the program will produce an error:

> Exception in thread "main"
> org.springframework.core.task.TaskRejectedException: Executor
> [java.util.concurrent.ThreadPoolExecutor@1f7911b[Running, pool size =
> 6, active threads = 0, queued tasks = 5, completed tasks = 18]] did
> not accept task: com.my.service.test.Test$1@1de8526; nested exception
> is java.util.concurrent.RejectedExecutionException: Task
> com.my.service.test.Test$1@1de8526 rejected from
> java.util.concurrent.ThreadPoolExecutor@1f7911b[Running, pool size =
> 6, active threads = 0, queued tasks = 5, completed tasks = 18]    at
> org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.execute(ThreadPoolTaskExecutor.java:305)
>   at com.my.service.test.Test.doWork(Test.java:42)    at
> com.my.service.test.Test.main(Test.java:27)   at
> sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)   at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>   at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>   at java.lang.reflect.Method.invoke(Method.java:606)     at
> com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
> Caused by: java.util.concurrent.RejectedExecutionException: Task
> com.my.service.test.Test$1@1de8526 rejected from
> java.util.concurrent.ThreadPoolExecutor@1f7911b[Running, pool size =
> 6, active threads = 0, queued tasks = 5, completed tasks = 18]    at
> java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
>   at
> java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
>   at
> java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
>   at
> org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.execute(ThreadPoolTaskExecutor.java:302)
>   ... 7 more

Who can tell me why, when I put a task to the thread pool, the poll first puts the task to workQueue?

like image 664
how8586 Avatar asked Mar 18 '15 09:03

how8586


People also ask

How does Java thread pool work?

Java Thread pool represents a group of worker threads that are waiting for the job and reused many times. In the case of a thread pool, a group of fixed-size threads is created. A thread from the thread pool is pulled out and assigned a job by the service provider.

Why do we need thread pool?

A thread pool helps mitigate the issue of performance by reducing the number of threads needed and managing their lifecycle. Essentially, threads are kept in the thread pool until they're needed, after which they execute the task and return the pool to be reused later.

How does Java handle exceptions in future?

Future Get Approach Lastly, uncaught exceptions can then be handled by blocking on the get() function of the Future, which is returned after submitting the task. If a task submitted with submit() terminates with an exception, it is rethrown by Future. get() and wrapped in an ExecutionException.


2 Answers

Rules for creating threads internally by Sun:

  1. If the number of threads is less than the corePoolSize, create a new thread to run a new task.

  2. If the number of threads is equal (or greater than) the corePoolSize, put the task into the queue.

  3. If the queue is full, and the number of threads is less than the maxPoolSize, create a new thread to run tasks in.

  4. If the queue is full, and the number of threads is greater than or equal to maxPoolSize, reject the task.

Your case is the last one where number of thread has reached to maxPoolSize i.e 6 and the queue is also full (number of task in queue is 5) so the task comes is rejected and gives TaskRejectedException.

like image 92
Sandeep Kumar Avatar answered Jan 11 '23 14:01

Sandeep Kumar


<property name="queueCapacity" value="5"/>

So the maximum ammount of "waiting" tasks to be executed is 5. Any futher submit performed before previous tasks are complete, will result in TaskRejectException

This information is also stored in exception itself

[java.util.concurrent.ThreadPoolExecutor@1f7911b[Running, pool size = 6, active threads = 0, queued tasks = 5, completed tasks = 18]

like image 41
Antoniossss Avatar answered Jan 11 '23 14:01

Antoniossss