【问题标题】:Java thread safetyJava线程安全
【发布时间】:2020-07-16 01:02:18
【问题描述】:
public void doSomething(){

    Object[] a = new Object[5];
    for(int i=0;i<5;i++) a[i] = executorService.submit(callable[i]).get();

}

这个线程安全吗?

谢谢

【问题讨论】:

  • a 只能被一个线程访问。
  • 为什么说a被两个线程访问了?
  • @JohannesKuhn @Joni executorService 正在产生新线程,不是吗?这里共有 5 个线程访问 a
  • 不,get 会阻塞,然后你的线程将结果分配到a 数组中。
  • 什么是callable[i]?目前,这些新线程都没有使用a,也没有使用a[i]

标签: java


【解决方案1】:

如图所示,代码不包含任何线程不安全的行为。

表达式callable[i]求值发生在主线程,get的结果赋值a[i]也发生在主线程线。您还可以获得帮助保持一致性的发生前关系:在主线程上对 submit 的调用发生在任何线程任务之前,这发生在对 get 的调用返回之前。

当然,callable[i] 本身执行的任何操作都必须以线程安全的方式完成,而且这实际上并没有启用并行性,因为您在开始下一个子任务之前阻塞了等待每个子任务的主线程。

编辑:您不会在编辑的代码中遇到写入冲突的问题,因为每个任务都访问不同的数组索引。此处概述的 visibility issues 不应该成为问题,因为 (IIRC) get() 的行为暗示了一个使写入可见的内存屏障。

【解决方案2】:

TL;DR - 是的,它是线程安全的。

a 中的数组是线程受限的:

  • 变量a被声明为局部变量,其他线程不可能看到它1
  • 您没有将a 中的值“发布”到任何其他线程。

因此数组或变量的状态与线程安全无关。

同样,i 受线程限制且不相关。

在提交调用和执行任务的线程之间存在 happens-before 关系,确保callable[i] 的状态对可调用对象的call 方法完全可见运行。

您分配给a 的值是在Future 上调用get() 的结果。 Future.get() 方法是线程安全的。它确保填充Future 的线程和调用get() 的线程之间存在happens-before 关系。

这一切加起来就是“线程安全”。


1 - 另一个调用 doSomething() 的线程将有一个不同的 a 变量实例,它将包含一个不同的 Object[]


唯一可能的问题是:

  • callables 数组是否安全地发布到此线程? (如果它是由其他线程创建或填充的。)如果不是,则可能会使用陈旧的数据。

  • callables 数组中的 Callable 实例是线程安全的……还是有效的线程受限?

但是这些事情并不是这段代码的真正“关注点”......并且无法在这段代码中解决。


关于这个例子还有一件事要说。下面这个语句其实是完全同步的。

a[i] = executorService.submit(callable[i]).get();

它的作用是将任务提交给执行器,然后等待(阻塞当前线程!)直到任务完成。结果,您的 5 个任务将一个接一个地运行……而不是并行运行

如果你想获得一些并行性,那么你应该这样做:

Object[] a = new Object[5];
Future<Object>[] f = new Future<>[5];
for (int i = 0; i < 5; i++) {
    f[i] = executorService.submit(callable[i]);
}
for (int i = 0; i < 5; i++) {
    a[i] = f[i].get();
}

如果您不想获得并行性,那么这在几乎所有用例中都会更好2

Object[] a = new Object[5];
for (int i = 0; i < 5; i++) {
    a[i] = callable[i].call();
}

2 - 一个不正确的情况是,如果您使用有界执行器服务来防止某类“密集”任务的资源利用淹没其他事物。

【讨论】:

  • 不,它不能。 a 是在此方法中声明的>>局部变量
猜你喜欢
  • 2013-06-06
  • 2012-02-25
  • 1970-01-01
  • 2021-12-16
  • 2010-11-14
  • 2014-09-16
  • 2011-11-23
  • 2010-10-12
  • 1970-01-01
相关资源
最近更新 更多