因为现在我要监控远程的一个方法,当这个方法执行超过一段时间时,我就要抛弃这个任务.那个方法我不能修改
测试代码:
public class MyThreadPool{
private static MyThreadPool myThreadPool = null;
/*** 线程的最小数*/
private static int corePoolSize = 5;
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, corePoolSize*2,10,TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(corePoolSize),new ThreadPoolExecutor.AbortPolicy());
private MyThreadPool(){}
public static MyThreadPool getInstance(){
if(null == myThreadPool){
System.out.println("MyThreadPool is creating!");
myThreadPool = new MyThreadPool();
}
return myThreadPool;
}
/**
* 执行任务
*/
public void exeWork(final MyWork work,int availableTime){
FutureTask<Boolean> future = new FutureTask<Boolean>(new Callable<Boolean>(){
public Boolean call(){
return work.doSometing();
}
});
executor.execute(future);
try{
future.get(availableTime, TimeUnit.SECONDS);
}catch(ExecutionException e1){
e1.printStackTrace();
}catch(InterruptedException e2){
e2.printStackTrace();
}catch(TimeoutException e3){
System.out.println("执行任务超时!");
}finally{
future.cancel(true);
closeExecutor();
}
}
public void closeExecutor(){
if(executor != null && executor.getActiveCount() ==0 && executor.getQueue().isEmpty()){
executor.shutdown();
}
}
public static int getCorePoolSize() {
return corePoolSize;
}
public static void setCorePoolSize(int corePoolSize) {
MyThreadPool.corePoolSize = corePoolSize;
}
}
Main 方法
public static void main(String[] args){
MyThreadPool threadPool = MyThreadPool.getInstance();
int availableTime = 5;
MyWork b = new BWork();
threadPool.exeWork(b, availableTime);
public class BWork implements MyWork{
public boolean doSometing(){
System.out.println("B starting...");
//模拟远程的方法 最坏的情况是死循环
while(true){
}
}
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
回答:
1 worker 最好以以下的形式进行循环
while (true) {
if (Thread.currentThread().isInterrupted()) {
return;
}
// do something
// thread sleep
}
这样打断该线程,以便结束该线程的生命周期。
其实executor.shutdown和shutdownnow也是调用thread.interupte来结束线程池的生命周期的
// shutdownnow
for (Worker w : workers) {
w.interruptNow();
}
// shutdown
for (Worker w : workers) {
w.interruptIfIdle();
}
2 其实最简单的方法是设置所创建的thread为守护线程就可以了。
thread factory 生成thread的时候设置t.setDaemon(true);
// t.setDaemon(true);
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize, corePoolSize * 2, 10, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(corePoolSize),
new ThreadFactory() {
public Thread newThread(Runnable r) {
// TODO Auto-generated method stub
final Thread t = new Thread(r);
t.setDaemon(true);
threads.add(t);
return t;
}
}, new ThreadPoolExecutor.AbortPolicy());
以下是全部代码
package test.thread.csdn;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class InterupteThreadTest {
private static InterupteThreadTest myThreadPool = null;
private static int corePoolSize = 5;
private static final List<Thread> threads = new ArrayList<Thread>();
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize, corePoolSize * 2, 10, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(corePoolSize),
new ThreadFactory() {
public Thread newThread(Runnable r) {
// TODO Auto-generated method stub
final Thread t = new Thread(r);
t.setDaemon(true);
threads.add(t);
return t;
}
}, new ThreadPoolExecutor.AbortPolicy());
private InterupteThreadTest() {
}
public static InterupteThreadTest getInstance() {
if (null == myThreadPool) {
System.out.println("MyThreadPool is creating!");
myThreadPool = new InterupteThreadTest();
}
return myThreadPool;
}
/**
* exeWork
*/
public void exeWork(int availableTime) {
FutureTask<Boolean> future = new FutureTask<Boolean>(
new Callable<Boolean>() {
public Boolean call() {
// dead loop mock
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
executor.execute(future);
try {
System.out.println(future.get(availableTime, TimeUnit.SECONDS));
} catch (ExecutionException e1) {
e1.printStackTrace();
} catch (InterruptedException e2) {
e2.printStackTrace();
} catch (TimeoutException e3) {
System.out.println("timeout!");
}
}
public void shut() {
executor.shutdown();
}
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
final InterupteThreadTest instance = InterupteThreadTest.getInstance();
instance.exeWork(4);
instance.shut();
}
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
回复:
1 worker 最好以以下的形式进行循环
while (true) {
if (Thread.currentThread().isInterrupted()) {
return;
}
// do something
}
首先感谢你的回帖,但是有几点前提我需要澄清:
首先 我为什么把 work.doSomething() 抽象来 就是因为 那是我即将调用别人的方法,我没办法改,我要做的就是判断 doSomething 这个方法是否已经超时,如果超了 那就结束(或抛出)这个线程。
另外main 方法不应该提供对操作池的操作 因为是开放给其他人用的。
还有 我在网上找了几天资料,说线程 是没办法被 kill 的 那 tomcat又是如何做到抛出超时连接的呢?