java在无限线程池执行器中不执行所有线程的原因是什么
我正在使用Executor服务
ExecutorService executor = Executors.newFixedThreadPool(20000);
我在ThreadSystem.java
类中有两个静态成员:
public static Integer count = 0;
public static Integer rejectedCount = 0;
然后我会给它添加线程:
for (i = 0; i < 20001; i++) {
Runnable worker = new MyThread();
try {
executor.execute(worker);
} catch (RejectedExecutionException ex) {
rejectedCount++;
}
}
executor.shutdown();
while (!executor.isTerminated()) {
}
线程内部:
@Override
public void run() {
ThreadSystem.count++;
try{
Thread.sleep(50);
}
catch(InterruptedException ex){
Logger.getLogger(MyThread.class.getName()).log(Level.SEVERE, ex.getMessage(),ex);
}
}
我得到的结果表明,存在未执行的线程,count
变量不等于创建的线程数,尽管引用被拒绝线程的rejectedCount
是0:
count:19488
rejected count: 0
那么,还有什么可以保证所有线程都将运行,以及这种情况的原因是什么:计数(可运行线程)不等于添加的线程数
# 1 楼答案
你的代码是种族状况的“完美例子”:你可以访问
未同步,因此多个线程可能会同时执行这一行:
这可能会导致写操作丢失,因为多个线程可能同时执行
ThreadSystem.count = ThreadSystem.count + 1
的等效操作,有些线程将读取操作的旧编号和尚未更新的编号要么使用合适的} 的东西作为计数器
synchronized
防护装置,要么使用沿着^{注意,在这种情况下,不能在
count
上同步,因为Integer
是一个不可变的对象,并且对装箱原语进行操作(int
到Integer
,long
到Long
,…)基本上是变量的赋值。对于这个给定的问题,使用AtomicInteger
是最好的解决方案你的^{也是如此 (不正确,因为这只由一个线程更新。)