Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理多线程使用的实例中的状态 让我们考虑下面的可变java类(Brian Goetz在实践中从java并发中获取):_Java_Spring_Multithreading - Fatal编程技术网

处理多线程使用的实例中的状态 让我们考虑下面的可变java类(Brian Goetz在实践中从java并发中获取):

处理多线程使用的实例中的状态 让我们考虑下面的可变java类(Brian Goetz在实践中从java并发中获取):,java,spring,multithreading,Java,Spring,Multithreading,假设这个类有一个由多个线程使用的实例,那么添加到该类中的以下哪些方法不会破坏其线程安全性 解决方案#1: 解决方案#2: 解决方案#3: 我的理解是,为了确保可见性,我需要确保字段值在CPU/核心缓存中正确刷新,因此解决方案2和3是可行的。有人能证实这一点吗 第二个问题: 假设我们有一个JavaSpring单例,它的一些状态保存在私有字段中。此单例由一些请求范围的bean使用。现在,每个请求都有自己的线程(有自己的调用堆栈,但有共享堆)。 由于单例的状态位于堆上,因此单例中定义的任何方法都应该以

假设这个类有一个由多个线程使用的实例,那么添加到该类中的以下哪些方法不会破坏其线程安全性

解决方案#1:

解决方案#2:

解决方案#3:

我的理解是,为了确保可见性,我需要确保字段值在CPU/核心缓存中正确刷新,因此解决方案2和3是可行的。有人能证实这一点吗

第二个问题: 假设我们有一个JavaSpring单例,它的一些状态保存在私有字段中。此单例由一些请求范围的bean使用。现在,每个请求都有自己的线程(有自己的调用堆栈,但有共享堆)。 由于单例的状态位于堆上,因此单例中定义的任何方法都应该以某种方式同步对其私有成员(=其状态)的访问,以确保可见性,例如使用lock、volatile、ReentrantLock等。 我理解对了吗?

线程安全的真正含义是什么

任何程序员在查看任何类时,都会对该类的行为产生期望。对我来说,“线程安全”意味着如果您从多个线程调用它的方法,您不必改变您的期望

与其说,“
SynchronizedInteger
是线程安全的”,我更愿意明确说明保证是什么,在这种情况下,它们很容易总结:它就像一个
volatile

您的“解决方案2”和“解决方案3”都保留了这一保证。你的解决方案1没有


假设我们有一个[共享对象]。[在]共享对象]上定义的任何方法都应该以某种方式同步对其[状态]的访问,以确保可见性[…]我做对了吗

对。这只是一个开始,但可能还不够。如果状态是复杂的(即,如果它取决于两个或多个变量之间的关系),则可能是某些更改状态的操作需要几个步骤,并且可能是在更改进行到一半时,状态将无效

在这种情况下,您需要使用互斥(例如,
synchronized
块),以确保除了进行更改的线程之外,没有其他线程会看到无效状态。这意味着您不仅需要在可能创建无效状态的每一位代码周围抛出一个互斥体;您还必须在必须保护的代码的每一位周围抛出一个互斥锁,以避免看到无效状态

@ThreadSafe
public class SynchronizedInteger {
  @GuardedBy("this") private int value;

  public synchronized int get() { return value; }
  public synchronized void set(int value) { this.value = value; }
}
public boolean isPositive() { return value > 0; }
public synchronized boolean isPositive() { return value > 0; }
public boolean isPositive() { return get() > 0; }