这个问题与我在Java并发主题中的作业分配有关。我的任务是生成新线程并按给定的concurrencyFactor
限制它们。也就是说,继续调度新线程,直到活动线程数小于或等于concurrencyFactor
。如果活动线程数等于concurrencyFactor
,则程序将等待,直到活动线程数减少到concurrencyFactor - 1
并创建一个新线程。
作为第一种方法,我使用ExecutorService
并通过Executors.newFixedThreadPool(concurrencyFactor);
创建了一个新的固定池,每当调用我的方法时,我只是向此池提交一个新的runnable。逻辑代码如下:
private final ExecutorService fixedPoolExecutor = Executors.newFixedThreadPool(concurrencyFactor);
public void handleRequest(final RequestHandler handler) {
if (handler == null) throw new IllegalArgumentException("Handler cannot be null");
fixedPoolExecutor.submit(new Runnable() {
@Override
public void run() {
handler.serviceRoutine();
}
});
}
现在,第二部分要求我实现相同的目标,但不使用执行程序。我想到了以下两种方法:
1)使用countDownLatch
但此锁存器将等待(即latch.await()
),直到activeCount
变为0
。我想等到countDown变为concurrencyFactor - 1
2)使用ThreadGroup
并等到threadGroup.activeCount() < concurrencyFactor
。但是,这种方法的问题是如何让传入的请求等到条件threadGroup.activeCount() < concurrencyFactor
满足?我已经使用以下代码来实现这种方法:
private final Lock lock = new ReentrantLock();
private final ThreadGroup threadGroup = new ThreadGroup("myGroup");
public void handleRequest(final RequestHandler handler) {
if (handler == null) throw new IllegalArgumentException("Handler cannot be null");
lock.lock();
try {
while (threadGroup.activeCount() >= concurrencyFactor) {
}
Thread t = new Thread(threadGroup, new Runnable() {
@Override
public void run() {
handler.service();
}
});
t.start();
} finally {
lock.unlock();
}
}
在第二种方法中,我可以用一些等待条件替换空白while循环吗?
对于任何新方法的上述方法或建议的任何建议将不胜感激。
答案 0 :(得分:1)
我建议使用case class Req[A <: RequestEntityMarshallable](entity: A)
。信号量将表示仍允许启动的线程数。最初,它保留的许可等于配置的并发因子。
在开始新线程之前,handleRequest方法需要从信号量获取许可。启动的线程应该在完成释放后再次允许。
示例代码:
Sempahore
(您可能希望以不同的方式处理可能的中断)