有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    你的代码是种族状况的“完美例子”:你可以访问

     public static Integer count = 0;
    

    未同步,因此多个线程可能会同时执行这一行:

     ThreadSystem.count++;
    

    这可能会导致写操作丢失,因为多个线程可能同时执行ThreadSystem.count = ThreadSystem.count + 1的等效操作,有些线程将读取操作的旧编号和尚未更新的编号

    要么使用合适的synchronized防护装置,要么使用沿着^{}的东西作为计数器

    注意,在这种情况下,不能在count上同步,因为Integer是一个不可变的对象,并且对装箱原语进行操作(intIntegerlongLong,…)基本上是变量的赋值。对于这个给定的问题,使用AtomicInteger是最好的解决方案

    你的^{也是如此 (不正确,因为这只由一个线程更新。)