Java并发:修改闩锁/线程组以实现执行器行为
这个问题与我在Java并发主题中的家庭作业有关。我的任务是生成新线程,并通过给定的Java并发:修改闩锁/线程组以实现执行器行为,java,multithreading,concurrency,executorservice,countdownlatch,Java,Multithreading,Concurrency,Executorservice,Countdownlatch,这个问题与我在Java并发主题中的家庭作业有关。我的任务是生成新线程,并通过给定的concurrencyFactor限制它们。也就是说,继续分派新线程,直到活动线程数小于或等于concurrencyFactor。如果活动线程的数量等于concurrencyFactor,程序将等待活动线程的数量减少到concurrencyFactor-1,并创建一个新线程 作为第一种方法,我使用了ExecutorService,并通过Executors创建了一个新的固定池
concurrencyFactor
限制它们。也就是说,继续分派新线程,直到活动线程数小于或等于concurrencyFactor
。如果活动线程的数量等于concurrencyFactor
,程序将等待活动线程的数量减少到concurrencyFactor-1
,并创建一个新线程
作为第一种方法,我使用了ExecutorService
,并通过Executors创建了一个新的固定池无论何时调用我的方法,我只是向这个池提交一个新的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();
}
});
}
现在,第二部分要求我实现同样的目标,但不使用executor。我想到了以下两种方法:
1) 使用countDownLatch
,但此闩锁将等待(即latch.wait()
),直到activeCount
变为0
。我只想等到倒计时变成concurrencyFactor-1
2) 使用ThreadGroup
并等待ThreadGroup.activeCount()
。但是,这种方法的问题是如何使传入的请求等待到条件threadGroup.activeCount()
满足时?我已将以下代码用于此方法:
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循环吗?
如对上述方法或任何新方法有任何建议,将不胜感激 我建议使用Sempahore
。信号量将表示仍然允许启动的线程数。最初,它持有与配置的并发因子相等的许可
在启动新线程之前,handleRequest方法需要从信号量获取许可证。启动的螺纹应在完成后再次释放
示例代码:
private final ThreadGroup threadGroup = new ThreadGroup("myGroup");
private final Semaphore concurrencyFactor = new Semaphore(CONCURRENCY_FACTOR);
public void handleRequest(final RequestHandler handler) throws InterruptedException {
if (handler == null) throw new IllegalArgumentException("Handler cannot be null");
concurrencyFactor.acquire(); // Get permit
Thread t = new Thread(threadGroup, new Runnable() {
@Override
public void run() {
try {
handler.service();
} finally {
concurrencyFactor.release(); // make sure to release permit
}
}
});
t.start();
}
(您可能希望以不同的方式处理可能出现的中断)分配是否强制您使用CountdownClatch?不,不强制。但是指令提示使用闩锁/线程/执行器来实现这一点。因为这似乎非常适合于信号量。问题是:我什么时候可以调用Semaphore.release()?我必须知道当前活动线程的数量。请参阅我的答案:)run方法中的try块是否确保只有在service
方法运行完成后才释放concurrencyFactor
?如果我们使用信号量,它确保释放许可证,尽管service()中抛出了任何异常,那么在这种情况下为什么要使用threadGroup
?这不会导致不必要的组管理开销吗?ThreadGroup无助于解决这个问题。我把它放在里面是因为我以为你是出于某种原因想要它。太好了!非常感谢你的帮助。