Java并发: Modifying latch/ThreadGroup to achieve Executor behaviour

标签 java multithreading concurrency executorservice countdownlatch

这个问题与我在 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/

相关文章:

java - Java Applet 中的元素对齐

java - 火狐未连接异常

android - HANDLER 不应该有自己的线程吗?

c++ - 用于线程控制的 volatile bool 是否被认为是错误的?

.net - 任务并行库启动的线程可以充当前台线程吗?

linux - Linux 线程中的文件段/节/记录锁

java - 输入字符串中的格式异常 (Java)

java - Android studio中eclipse有没有像ctrl + shift + T之类的东西可以看到打开类型窗口

java - Clojure/Java 中的 Goroutine 等价物

java - ConcurrentModificationException 在 Java 中递归使用 Maps