gpt4 book ai didi

java - ExecutorService 和 AtomicInteger : RejectedExecutionException

转载 作者:行者123 更新时间:2023-12-02 10:35:59 32 4
gpt4 key购买 nike

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

 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);
}

我有错误

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)

我应该如何实现它。

最佳答案

这里不需要使用 AtomicInteger,因为您的 Runnable lambda 函数调用保证按顺序执行(通过新的 SingleThreadExecutor)。此外,您的 Runnable lambda 代码需要任何时间来执行(例如 2 毫秒),您的主循环将排队远远超过达到限制所需的 10 个任务。如果您在 Runnable lambda 函数中添加 2ms sleep ,并在 do/while 循环中添加一个计数器,并在最后打印计数器的值以查看排队的 Runnable 实例数量,您就会看到这种情况发生。

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

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) {
}
}

这是一个修复并发问题并将执行器管理移出它不真正属于的工作线程的版本:

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) {

}
}

关于java - ExecutorService 和 AtomicInteger : RejectedExecutionException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53291764/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com