Java并发:修改闩锁/线程组以实现执行器行为

Java并发:修改闩锁/线程组以实现执行器行为,java,multithreading,concurrency,executorservice,countdownlatch,Java,Multithreading,Concurrency,Executorservice,Countdownlatch,这个问题与我在Java并发主题中的家庭作业有关。我的任务是生成新线程,并通过给定的concurrencyFactor限制它们。也就是说,继续分派新线程,直到活动线程数小于或等于concurrencyFactor。如果活动线程的数量等于concurrencyFactor,程序将等待活动线程的数量减少到concurrencyFactor-1,并创建一个新线程 作为第一种方法,我使用了ExecutorService,并通过Executors创建了一个新的固定池

这个问题与我在Java并发主题中的家庭作业有关。我的任务是生成新线程,并通过给定的
concurrencyFactor
限制它们。也就是说,继续分派新线程,直到活动线程数小于或等于
concurrencyFactor
。如果活动线程的数量等于
concurrencyFactor
,程序将等待活动线程的数量减少到
concurrencyFactor-1
,并创建一个新线程

作为第一种方法,我使用了
ExecutorService
,并通过
Executors创建了一个新的固定池
    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无助于解决这个问题。我把它放在里面是因为我以为你是出于某种原因想要它。太好了!非常感谢你的帮助。