Java ExecutorService和AtomicInteger:RejectedExecutionException
我希望atomicInteger的值为100,然后程序终止Java ExecutorService和AtomicInteger:RejectedExecutionException,java,executorservice,atomicinteger,Java,Executorservice,Atomicinteger,我希望atomicInteger的值为100,然后程序终止 public static void main(String[] args) throws InterruptedException { ExecutorService executor = Executors.newSingleThreadExecutor(); AtomicInteger atomicInteger = new AtomicInteger(0); do {
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)
我应该如何实现它。您只需更改while循环以检查所需的条件,然后关闭执行器。这里不需要使用AtomicInteger,因为您的可运行lambda函数调用保证按顺序执行(由新的SingleThreadExecutor执行)。此外,如果您的可运行lambda代码需要花费任何时间来执行(例如2ms),那么您的主循环将排队等待超过10个任务,以达到您的限制。如果在可运行lambda函数中添加2ms sleep,并在do/while循环中添加一个计数器,并在末尾打印计数器的值以查看排队的可运行实例数,则可以看到这种情况 假设希望使用并发线程测试此代码,则需要将对newSingleThreadPool的调用替换为newFixedThreadPool。当使用并发线程时,代码采用的方法是有问题的。在下面的代码中,我切换到了newFixedThreadPool,添加了一个计数器,这样我们就可以看到有多少任务排队,并在可运行的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) {
}
}
下面是一个版本,它修复了并发性问题,并将executor管理从不属于它的工作线程中移出:
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) {
}
}
private static int LIMIT=100;
私有静态int增量=10;
公共静态void main(字符串[]args){
ExecutorService executor=Executors.newFixedThreadPool(2);
AtomicInteger AtomicInteger=新的AtomicInteger(0);
对于(int i=0;i{
暂停(2);
System.out.println(“atomicInt=“+atomicInteger.getAndAdd(增量));
System.out.flush();
暂停(2);
});
}
executor.shutdown();
而(!executor.isTerminated()){
System.out.println(“尚未终止的执行人”);
System.out.flush();
暂停(4);
}
System.out.println(“final atomicInt=“+atomicInteger.get());
}
公共静态无效暂停(长毫秒){
试一试{
睡眠(毫秒);
}捕获(中断异常例外){
}
}
您可能应该修复executor.shutdownNown()代码>首先如果我删除它,如何停止它?