取消 Callable 实现无法正常工作
Cancelling a Callable implementation doesn't work correctly
我开始迁移到 java 线程池,而不是拥有我的线程池框架。因此,我为此目的编写了一个示例。实际上,最大的要求是如果运行ning 线程执行得太迟,就停止它。另外,为了达到这个目的,我使用了cancel
Future
class的方法。总之,问题是 运行ning 线程在取消后并没有停止,而是继续执行。我的代码是:
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);
}
}
}
spring 上下文 (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>
当我 运行 程序时,我得到以下结果:
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,
(我没有写出所有输出,因为它会永远持续下去。)
我的问题告诉你了,我还有一个问题:当我取消线程并停止它时,线程return到线程池,另一个任务可以被执行吗?
如果您的任务已经 运行,则无法取消,因为该任务不会执行任何检查线程是否被中断的操作。
如果您将循环变成 while(!Thread.currentThread().isInterrupted())
,cancel(true)
可以尝试中断线程,然后循环会注意到这一点。
在任务中使用可中断操作也会使其可取消。
我开始迁移到 java 线程池,而不是拥有我的线程池框架。因此,我为此目的编写了一个示例。实际上,最大的要求是如果运行ning 线程执行得太迟,就停止它。另外,为了达到这个目的,我使用了cancel
Future
class的方法。总之,问题是 运行ning 线程在取消后并没有停止,而是继续执行。我的代码是:
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);
}
}
}
spring 上下文 (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>
当我 运行 程序时,我得到以下结果:
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,
(我没有写出所有输出,因为它会永远持续下去。)
我的问题告诉你了,我还有一个问题:当我取消线程并停止它时,线程return到线程池,另一个任务可以被执行吗?
如果您的任务已经 运行,则无法取消,因为该任务不会执行任何检查线程是否被中断的操作。
如果您将循环变成 while(!Thread.currentThread().isInterrupted())
,cancel(true)
可以尝试中断线程,然后循环会注意到这一点。
在任务中使用可中断操作也会使其可取消。