首页 > 解决方案 > 如何使这个线程安全?

问题描述

这个线程安全吗?每次我不确定如何使这个线程安全时,我都会得到不同的结果。我的目标是计算从 5 -10000 开始的素数数量,但每次计算都使用一个线程。我想跟踪素数的总数。如果我运行下面的代码,我有时会得到 21,有时会得到 22。

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.io.IOException;

public class Main {
     private static AtomicInteger count =new AtomicInteger(0);
    private static ExecutorService ex = Executors.newFixedThreadPool(100);
   
     public static void main(String []args) throws IOException {
        int x =5;
        while(x < 90){
            final int index =x;
           ex.execute(new Runnable(){
                public void run(){
                    synchronized(count){
                        if(isPrime(index)){
                            count.incrementAndGet();
                        }
                    }
                }
            });
            x++;
            //new Thread(task).start();
        }
        ex.shutdown();
        System.out.println(count.get()+ "this how many numbers are  prime");
     }
     
    public static boolean isPrime(int n)
    {
        // Corner cases
        if (n <= 1)
            return false;
        if (n <= 3)
            return true;
 
        // This is checked so that we can skip
        // middle five numbers in below loop
        if (n % 2 == 0 || n % 3 == 0)
            return false;
 
        for (int i = 5; i * i <= n; i = i + 6)
            if (n % i == 0 || n % (i + 2) == 0)
                return false;
 
        return true;
    }
}

标签: javamultithreadingthread-safetyconcurrent.futures

解决方案


添加函数shutdownAndAwaitTermination(ExecutorService ex)解决了这个问题,而不是仅仅调用ex.shutdown();我调用shutdownAndAwaitTermination(ex);

 public static void shutdownAndAwaitTermination(ExecutorService ex) {
    ex.shutdown(); // Disable new tasks from being submitted
    try {
     // Wait a while for existing tasks to terminate
     if (!ex.awaitTermination(60, TimeUnit.SECONDS)) {
       ex.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!ex.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     ex.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 } 

推荐阅读