这个问题与我在 Java 并发主题中的作业有关。我的任务是生成新线程并通过给定的 concurrencyFactor
限制它们。也就是说,继续分派(dispatch)新线程,直到 Activity 线程数小于或等于concurrencyFactor
。 。如果 Activity 线程数等于concurrencyFactor
,程序将等待,直到 Activity 线程数减少到 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 循环吗?
任何有关上述方法的建议或任何新方法的建议将不胜感激。
最佳答案
我建议使用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();
}
(您可能希望以不同的方式处理可能的中断)
关于Java并发: Modifying latch/ThreadGroup to achieve Executor behaviour,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43502001/