【问题标题】:concurrent access to array without safety在不安全的情况下并发访问数组
【发布时间】:2018-12-25 14:41:12
【问题描述】:

字段值是 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();
        }

【问题讨论】:

  • 你没有显示你的执行者的定义。如果是单线程执行器,它会串行执行任务,而不是并行执行。
  • 好的,我已经添加了。
  • getValues(); 的定义是什么?我假设您必须使用Future.get(),在这种情况下呼叫被阻塞。
  • 每个逻辑核一次只能运行一个线程,其他的都需要等待。我建议使用并行流来更有效地安排这个。
  • 我不明白一件事,我的处理器有4核8线程。那么我可以使用 executor 或 4 运行 8 个线程吗?因为你说的是​​核心......

标签: java concurrency


【解决方案1】:

假设您的 threads 是 10。您可能认为您的代码在 callables 列表中生成 10 个可调用对象,然后运行 ​​invokeAll。但实际上,您的代码会为每个 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 应该在循环内,invokeAllgetValues 应该在循环之外。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-06
    相关资源
    最近更新 更多