java - 多线程中 Collection.sort() 中的 NullpointerException

标签 java multithreading nullpointerexception executorservice

我有一个类应该使用多线程测试我的斐波那契函数

public class PerformanceTesterImpl implements PerformanceTester{
    public static List<Long> executionTimesList = new ArrayList();
    public static List<Runnable> tasksList = new ArrayList();
    public int fib;
    public PerformanceTestResult performanceTestResult;

    @Override
    public PerformanceTestResult runPerformanceTest(Runnable task, int calculationCount, int threadPoolSize) {

        for(int i=0; i<calculationCount; i++){
            tasksList.add(createTask(fib));
        }

        ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);
        for(Runnable r : tasksList){
            executor.execute(r);
        }
        executor.shutdown();  

        try {
            executor.awaitTermination(1, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // Here all threads should complete all work. Is it OK?
        mapValues();
        return performanceTestResult;
    }

    private PerformanceTestResult mapValues(){
        Collections.sort(executionTimesList);
        performanceTestResult = new PerformanceTestResult(getSum(executionTimesList), (Long)executionTimesList.get(0), (Long)executionTimesList.get(executionTimesList.size()-1));
        return performanceTestResult;
    }


    public  Runnable createTask (final int n) {
        fib = n;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                long startTime = System.currentTimeMillis();
                FibCalc fibCalc = new FibCalcImpl();
                fibCalc.fib(n);
                long executionTime = System.currentTimeMillis() - startTime;
                executionTimesList.add(executionTime);
            }
        };
        return runnable;
    }


    private static long getSum(List<Long> executionTimes){
        long sum = 0;
        for(long l : executionTimes){
            sum += l;
        }
        return sum;
    }
}

但有时 NULL 会出现在我的集合中,当我尝试对executionTimeList 进行排序时,我会收到 NullpointerException。我认为执行线程有问题。我应该怎么做才能纠正这个异常?

最佳答案

ArrayList 不是线程安全的。

来自 Javadoc:

 * If multiple threads access an <tt>ArrayList</tt> instance concurrently,
 * and at least one of the threads modifies the list structurally, it
 * <i>must</i> be synchronized externally.  (A structural modification is
 * any operation that adds or deletes one or more elements, or explicitly
 * resizes the backing array; merely setting the value of an element is not
 * a structural modification.)  This is typically accomplished by
 * synchronizing on some object that naturally encapsulates the list.

 * If no such object exists, the list should be "wrapped" using the
 * {@link Collections#synchronizedList Collections.synchronizedList}
 * method.  This is best done at creation time, to prevent accidental
 * unsynchronized access to the list:<pre>
 *   List list = Collections.synchronizedList(new ArrayList(...));</pre>

当您从多个线程调用add时,ArrayList可能处于不一致的状态。您应该同步对其的访问。

尝试:

        public void run() {
            long startTime = System.currentTimeMillis();
            FibCalc fibCalc = new FibCalcImpl();
            fibCalc.fib(n);
            long executionTime = System.currentTimeMillis() - startTime;
            synchronized (this) {
                executionTimesList.add(executionTime);
            }
        }

关于java - 多线程中 Collection.sort() 中的 NullpointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30692880/

相关文章:

java - Android Cursor NPE dumpCursorToString 返回值

java - 非常奇怪的 Android NullPointerException

java - 如何用简单的文本创建 JFrame?

java - AndroidManifest.xml 中的应用程序无法通过谷歌搜索警告进行索引

java - JNDI 在不检索所有数据的情况下获取 LDAP 搜索的大小

c# - 多线程 WPF Application : Dispatcher Invoke. 更高效的方法?

c++ - send(),返回 Winsock 错误 10038

java - 为什么要对字符串或其他对象使用 wait 方法?

java - 什么是NullPointerException,我该如何解决?

java - Android 上通过蓝牙进行数据处理导致数据完整性不佳