简体   繁体   English

取消可调用的实现无法正常工作

[英]Cancelling a Callable implementation doesn't work correctly

I began to immigrate to java thread pool instead of own my framework for pooling threads. 我开始迁移到Java线程池,而不是拥有自己的线程池框架。 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. 另外,为了达到这个目的,我使用Future类的cancel方法。 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: 春天的上下文( threadpool.xml )是:

<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? 我告诉你我的问题,我还有另一个问题:当我取消线程并停止它时,线程返回线程池,可以执行另一个任务吗?

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. 如果将循环放入while(!Thread.currentThread().isInterrupted())cancel(true)可以尝试中断线程,然后循环会注意到该线程。

Using interruptible operations inside the task would also make it cancelable. 在任务内部使用可中断的操作也会使其取消。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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