【发布时间】:2017-09-16 01:16:53
【问题描述】:
这个问题与我在 Java 并发主题中的作业有关。我的任务是生成新线程并通过给定的concurrencyFactor 限制它们。也就是说,继续调度新线程,直到活动线程数小于或等于concurrencyFactor。如果活动线程数等于concurrencyFactor,程序将等待活动线程数减少到concurrencyFactor - 1并创建一个新线程。
作为第一种方法,我使用ExecutorService 并通过Executors.newFixedThreadPool(concurrencyFactor); 创建了一个新的固定池,每当调用我的方法时,我只是向该池提交一个新的可运行文件。逻辑代码如下:
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。我只想等到倒计时变成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循环吗?
任何关于上述方法的建议或任何新方法的建议都将不胜感激。
【问题讨论】:
-
作业是否强制您使用 CountDownLatch?
-
不,它不强制。但是说明提示使用锁存器/线程/执行器来实现这一点。
-
因为这似乎非常适合 Semaphore。
-
问题是:什么时候可以调用semaphore.release()?我必须知道当前活动线程的数量。
-
看我的回答:)
标签: java multithreading concurrency executorservice countdownlatch