首页 > 解决方案 > 在不安全的情况下并发访问数组

问题描述

字段值是 float[] ,我有点困惑,因为当我调试代码时,我遇到的问题是,当一个线程正在工作并使用我的 float[] 值数组时,其他线程正在等待这是否正常?我不关心数组上的错误数据,因为线程正在计算数组的不同部分

ExecutorService executor = Executors.newFixedThreadPool(threads);

List<PartOfImage> callables;
        for(int j=0;j<200;++j)
        for(int i=0;i<threads;++i){
            callables=new LinkedList<>();
            callables.add(new PartOfImage(values,width,(height/threads)*i, (height/threads)*(i+1),
                    oldImage,((i+1)%threads)==0,(i%threads)==0));

        List<Future<Object>> answers =   executor.invokeAll(callables);


         oldImage=getValues();
        }

标签: javaconcurrency

解决方案


假设您threads是 10。您可能认为您的代码在callables列表中生成 10 个可调用对象,然后运行invokeAll​​. 但实际上,您的代码为 each 执行整个块i

callables=new LinkedList<>();
callables.add(new PartOfImage(values,width,(height/threads)*i, (height/threads)*(i+1),
              oldImage,((i+1)%threads)==0,(i%threads)==0));

List<Future<Object>> answers =   executor.invokeAll(callables);
oldImage=getValues();

这意味着它创建一个包含一个可调用对象的列表,并invokeAll在该列表上运行,然后转到下一个i,创建一个包含一个可调用对象的列表,invokeAll在该(单任务)列表上运行,依此类推。

所以实际上它是连续运行的。您应该将列表的创建移到i循环之外,只有callables.add应该在循环内,而invokeAllandgetValues应该在循环之外。


推荐阅读