首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ExecutorService和AtomicInteger : RejectedExecutionException

ExecutorService和AtomicInteger : RejectedExecutionException
EN

Stack Overflow用户
提问于 2018-11-14 01:10:06
回答 2查看 380关注 0票数 0

我希望atomicInteger的值为100,然后程序终止。

代码语言:javascript
复制
 public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        AtomicInteger atomicInteger = new AtomicInteger(0);
        do {
            executor.submit(() -> {
                System.out.println(atomicInteger.getAndAdd(10));
                if (atomicInteger.get() == 100) {
                    //executor.shutdownNown();
                }
            });
        } while (true);
    }

我有错误

代码语言:javascript
复制
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@1d8d10a rejected from java.util.concurrent.ThreadPoolExecutor@9e54c2[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 10]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1374)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
    at java.util.concurrent.Executors$DelegatedExecutorService.submit(Executors.java:678)

我应该如何实现它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-15 01:35:18

这里不需要使用AtomicInteger,因为可以运行的lambda函数调用保证按顺序执行(通过新的SingleThreadExecutor)。而且,运行的lambda代码需要任何时间来执行(例如,2ms),您的主循环将排队等待超过10个任务,以达到您的限制。如果在可运行的lambda函数中添加2ms睡眠,并在do/while循环中添加一个计数器,并在末尾打印计数器的值,查看您排队排队的实例数量,就会看到这种情况。

假设您希望用并发线程测试此代码,则需要用newFixedThreadPool替换对newFixedThreadPool的调用。当使用并发线程时,代码所采用的方法是有问题的。在下面的代码中,我切换到newFixedThreadPool,添加了一个计数器,这样我们就可以看到有多少任务在排队,并添加到可运行的lambda函数中的短暂停中,仅仅是为了表示少量的工作。当我执行这个程序时,atomicInteger变得大于13000,程序崩溃时java.lang.OutOfMemoryError: GC开销限制超过了,这是因为您的可运行函数总是将10添加到atomicInteger中,而不管它的当前值如何。而且,代码排队的任务比它所需要的还要多。下面是这些小改动的代码,说明了这个问题。

代码语言:javascript
复制
public static void main(String[] args) {
    ExecutorService executor = Executors.newFixedThreadPool(3);
    AtomicInteger atomicInteger = new AtomicInteger(0);
    int i=0;
    do {
        executor.submit(() -> {
            pause(2); // simulates some small amount of work.
            System.out.println("atomicInt="+atomicInteger.getAndAdd(10));
            pause(2); // simulates some small amount of work.
            if (atomicInteger.get() == 100) {
                System.out.println("executor.shutdownNow()");
                System.out.flush();
                executor.shutdownNow();
            }
        });
        if (atomicInteger.get() == 100) {
            break;
        }
    } while (true);
    System.out.println("final atomicInt="+atomicInteger.get());
    System.out.println("final tasks queued="+i);
}
public static void pause(long millis) {
    try {
        Thread.sleep(millis);
    } catch (InterruptedException ex) {
    }
}

下面是一个解决并发问题并将executor管理从不属于它的工作线程中移出的版本:

代码语言:javascript
复制
private static int LIMIT = 100;
private static int INCREMENT = 10;

public static void main(String[] args) {
    ExecutorService executor = Executors.newFixedThreadPool(2);
    AtomicInteger atomicInteger = new AtomicInteger(0);
    for (int i=0; i < LIMIT/INCREMENT; i++) {
            executor.submit(() -> {
                pause(2);
                System.out.println("atomicInt=" + atomicInteger.getAndAdd(INCREMENT));
                System.out.flush();
                pause(2);
            });
    }
    executor.shutdown();
    while (!executor.isTerminated()) {
        System.out.println("Executor not yet terminated");
        System.out.flush();
        pause(4);
    }
    System.out.println("final atomicInt=" + atomicInteger.get());
}

public static void pause(long millis) {
    try {
        Thread.sleep(millis);
    } catch (InterruptedException ex) {

    }
}
票数 1
EN

Stack Overflow用户

发布于 2018-11-14 01:40:30

您应该更改while循环,以检查所需的条件,并在此之后关闭执行程序。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53291764

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档