Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ExecutorService和AtomicInteger:RejectedExecutionException_Java_Executorservice_Atomicinteger - Fatal编程技术网

Java ExecutorService和AtomicInteger:RejectedExecutionException

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 {

我希望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)

我应该如何实现它。

您只需更改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()首先如果我删除它,如何停止它?