我有一个单线程的固定池。当我提交新任务时,我想要停止除最后一个之外的所有旧线程。
private class MyPool extends ThreadPoolExecutor {
public MyPool(long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
super(1, 1, keepAliveTime, unit, workQueue);
}
public boolean isReady() {
return semaphore;
}
@Override
public <T> Future<T> submit(Callable<T> task) {
// Iterate all existed task and stop
Future<T> future = super.submit(task);
return future;
}
private volatile boolean semaphore;
}
运行任务代码:
private class MyTask implements Runnable {
private volatile boolean isRun = true;
private int id;
public MyTask(int id) {
this.id = id;
}
public void stop() {
isRun = false;
}
@Override
public void run() {
try {
System.out.println("Start " + id);
if (isRun) {
Thread.sleep(1000);
System.out.println("Stop " + id);
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
我创建了自己的类,但它没有正确工作,因为信号量对新任务也有影响。最好的方法是什么?
答案 0 :(得分:1)
如果提交了新的Callable
,则此ThreadPoolExecutor会终止正在运行的线程:
class MyPool extends ThreadPoolExecutor {
private volatile Thread activeThread = null;
private static final Field FutureTask$runner;
static {
try {
FutureTask$runner = FutureTask.class.getDeclaredField("runner");
FutureTask$runner.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new Error(e);
}
}
private static Thread getThread(FutureTask<?> task) {
try {
return (Thread) FutureTask$runner.get(task);
} catch (IllegalAccessException e) {
throw new Error(e);
}
}
public MyPool() {
super(1, 1,
//whatever here
5000, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>());
}
@Override
public <T> Future<T> submit(Callable<T> task) {
if(activeThread != null) {
activeThread.stop(); //kill
}
FutureTask<T> activeTask = (FutureTask<T>)super.submit(task);
activeThread = getThread(activeTask); //steal thread reference for killing
return activeTask;
}
}