我希望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)我应该如何实现它。
发布于 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中,而不管它的当前值如何。而且,代码排队的任务比它所需要的还要多。下面是这些小改动的代码,说明了这个问题。
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) {
}
}发布于 2018-11-14 01:40:30
您应该更改while循环,以检查所需的条件,并在此之后关闭执行程序。
https://stackoverflow.com/questions/53291764
复制相似问题