英文:
ThreadPoolExecutor : Pull out hanged tasks
问题
我已经实现了ThreadPoolExecutor来调用任务。
而且,由于核心/队列大小配置不正确,任务似乎在I/O操作上挂起了。
我希望可以将那个挂起的线程中止,
以便队列中的其他线程开始执行。
有没有办法列出ThreadPoolExecutor中的线程,并中止挂起的线程?
英文:
I have implemented ThreadPoolExecutor to invoke a task.
And It seems tasks got hanged on I/O because of the core/queue size misconfiguration.
I want to pull the hanging thread out
so that the other threads in my queue starts executing.
Is there any way to list the threads inside a threadpoolexecutor and pull out the hanging thread?
答案1
得分: 0
import java.util.Set;
import java.util.concurrent.*;
public class ActiveTasksThreadPool extends ThreadPoolExecutor {
private final ConcurrentHashMap<Runnable, Boolean> activeTasks = new ConcurrentHashMap<>();
public ActiveTasksThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
activeTasks.put(r, Boolean.TRUE);
super.beforeExecute(t, r);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
activeTasks.remove(r);
}
public Set<Runnable> getActiveTasks() {
// the returned set will not throw a ConcurrentModificationException.
return activeTasks.keySet();
}
}
// In order to set a timeout on thread tasks with `Future`:
ActiveTasksThreadPool executor = new ActiveTasksThreadPool(maxTasks, maxTasks, 10, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
Executors.newFixedThreadPool(2);
List<Future<Integer>> resultList = new ArrayList<>();
Random random = new Random();
for (int i=0; i<4; i++)
{
Integer number = random.nextInt(10);
FactorialCalculator calculator = new FactorialCalculator(number);
Future<Integer> result = executor.submit(calculator);
result.get(100, TimeUnit.MILLISECONDS); // here is a timeout of 100 milisecond
}
英文:
You have control over the used executor, you could use the ThreadPoolExecutor's beforeExecute and afterExecute methods to keep track of running tasks and use that to create a getActiveTasks method.
import java.util.Set;
import java.util.concurrent.*;
public class ActiveTasksThreadPool extends ThreadPoolExecutor {
private final ConcurrentHashMap<Runnable, Boolean> activeTasks = new ConcurrentHashMap<>();
public ActiveTasksThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
activeTasks.put(r, Boolean.TRUE);
super.beforeExecute(t, r);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
activeTasks.remove(r);
}
public Set<Runnable> getActiveTasks() {
// the returned set will not throw a ConcurrentModificationException.
return activeTasks.keySet();
}
In order to set a timeout on thread tasks with Future
:
ActiveTasksThreadPool executor = new ActiveTasksThreadPool(maxTasks, maxTasks, 10, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());Executors.newFixedThreadPool(2);
List<Future<Integer>> resultList = new ArrayList<>();
Random random = new Random();
for (int i=0; i<4; i++)
{
Integer number = random.nextInt(10);
FactorialCalculator calculator = new FactorialCalculator(number);
Future<Integer> result = executor.submit(calculator);
result .get(100, TimeUnit.MILLISECONDS); // here is a timeout of 100 milisecond
}
专注分享java语言的经验与见解,让所有开发者获益!
评论