0

I began to immigrate to java thread pool instead of own my framework for pooling threads. So, I wrote a sample for this aim. Actually, the largest requirement is to stop the running thread if its execution is too late. In addition, to achieve this purpose, I use cancel method of Future class. In conclusion, the problem is the running thread after canceling it was not stopped and it's continuing to execute. My code is :

public class ThreadPoolWarmup
{
    static class CountDownClock1 implements Callable<Boolean>
    {
        public Boolean call() throws Exception
        {
            String threadName = Thread.currentThread().getName();
            long i = 0;
            for (; ; )
            {
                if ((i % 1000000000) == 0)
                    System.out.println(i + ", ");
                i++;
            }
        }
    }

    public static void main(String[] args)
    {
        Future<Boolean> f1 = null;
        try
        {
            ApplicationContext context = new ClassPathXmlApplicationContext("threadpool.xml");
            ThreadPoolTaskExecutor taskExecutor = (ThreadPoolTaskExecutor) context.getBean("taskExecutor");
            f1 = taskExecutor.submit(new CountDownClock1());
            Boolean b1 = f1.get(15,TimeUnit.SECONDS);
            System.out.println("Reslt is ===========>>>>> " +  b1);
        }
        catch (Exception t)
        {
            t.printStackTrace();
            boolean c1 = f1.cancel(true);
            System.out.println("Cancel result ======>>>>>>>>>  " + c1);
        }
    }
}

also the spring context (threadpool.xml) is:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<bean id="taskExecutor"  class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="3" />
    <property name="maxPoolSize" value="3" />
    <property name="WaitForTasksToCompleteOnShutdown" value="true" />
    <property name="queueCapacity" value="-1"/>
    <property name="keepAliveSeconds" value="30"/>
</bean>

and when I run the program I get following the rerult:

0, 
1000000000, 
2000000000, 
3000000000, 
4000000000, 
5000000000, 
java.util.concurrent.TimeoutException
    at java.util.concurrent.FutureTask.get(FutureTask.java:205)
    at thread.ThreadPoolWarmup.main(ThreadPoolWarmup.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Cancel result ======>>>>>>>>>  true
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
6000000000, 
7000000000, 
8000000000, 
9000000000, 
10000000000, 
11000000000, 
12000000000, 
13000000000, 
14000000000, 

(I didn't write all output because it's continuing forever.)

I told you my problem and I have another question: When I cancel the thread and stop it, the thread return to the thread pool and another task can be executed by that?

Sam
  • 6,770
  • 7
  • 50
  • 91

1 Answers1

1

Your task is simply uncancellable if already running, because the task doesn't perform anything to check whether the thread is interrupted.

If you make your loop into a while(!Thread.currentThread().isInterrupted()) the cancel(true) can try to interrupt the thread, which would then be noticed by the loop.

Using interruptible operations inside the task would also make it cancelable.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • can you link me to a question explaining why the authors `call` method even compiles? I understand that the `for` loop is infinite, but I thought you'd still need a return statement somewhere! For example `Object foo() {for(;;);}` will compile. So weird! – flakes Sep 19 '17 at 07:50
  • @flakes The possible outcomes are either an infinite loop or an exceptional exit from the method. The compiler is smart enough to not to insist on a return value which can never be used. – Kayaman Sep 19 '17 at 07:52
  • 2
    @flakes see https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.7 . The only prohibition is if control can reach the end of the method, which doesn't happen here. – Pete Kirkham Sep 19 '17 at 07:55
  • @PeteKirkham I'm slightly mind-blown by the `Exception` example! I use it so often and never questioned it! Thanks! – flakes Sep 19 '17 at 07:58
  • @Kayaman Thanks for the advice but I want to discard the thread from the out. It means I would like to control `CountDownClock1` from the out by its time and when the time is exceeded its thread is stopped and no more continue. Is there any solution? – Sam Sep 19 '17 at 10:42
  • 1
    No. You can't do that. If you've written an ridiculous loop that spins the CPU, that's your fault. If your task is more realistic, then interrupting the thread will work just fine. – Kayaman Sep 19 '17 at 10:46
  • My code is an example and you have to be sure my real logic isn't ridiculous. However, maybe I will have some loops with the heavy process at the real application but my thread still doesn't notify an interrupt has happened. Am I right? – Sam Sep 19 '17 at 13:21
  • A thread interruption can't be detected at just any time, as you've seen with your example. If you're doing heavy looping without operations that check for interrupt status, you need to check it yourself. – Kayaman Sep 19 '17 at 13:23
  • @Kayaman Yeah, I realize now. Additionally, it's odd that Java doesn't see a way for terminating a thread from out? Maybe I don't have a good understanding of the threading framework. What's your opinion? – Sam Sep 19 '17 at 13:29
  • You don't want to kill a thread. You want to cancel a task. Besides, you're the one who wrote your own threadpool, don't you have a good understanding of Java threads? – Kayaman Sep 19 '17 at 13:32
  • You're right. I meant about understanding interrupt mechanism in java :) All in all, thanks for your help. – Sam Sep 19 '17 at 13:40