线程安全和不可变性(Thread Safety and Immutability)
来源:互联网 发布:淘宝上外贸原单 编辑:程序博客网 时间:2024/04/30 08:28
原文链接:http://tutorials.jenkov.com/java-concurrency/thread-safety-and-immutability.html
竞争条件只会在多个线程访问相同的资源并且一个或多个线程改写这个资源的情况下发生。如果多个线程只是同时读取相同的资源不会导致竞争条件的发生。
我们可以通过某种手段让共享的对象不可改变,从而可以确保这些不可改变的共享对象不会被任何一个线程改变,因此这些不可改变的对象是线程安全的。下面是一个例子:
public class ImmutableValue { private int value = 0; public Immutablevalue(int value) { this.value = value; } public int getValue() { return this.value; } }
注意,ImmutableValue 类的实例的值是通过构造方法传递的、 ImmutableValue 类是没有 set 方法的,一旦 ImmutableValue 类的实例被创建以后就不能改变它的值。 ImmutableValue 类的实例是不可改变的,可以通过 getValue() 方法来读取它的值。
如果需要在这个 ImmutableValue 类的实例上执行操作,可以把不可变对象原有的值结合需要的操作产生一个新的值,然后用这个新的值新建一个实例,最后把这个新建的实例返回。下面是一个 add 操作的例子:
public class ImmutableValue { private int value = 0; public ImmutableValue(int value) { this.value = value; } public int getValue() { return this.value; } public ImmutableValue add(int valueToAdd) { return new ImmutableValue(this.value + valueToAdd); } }
注意, add() 方法用 add 操作的结果重新构造了一个 ImmutableValue 类的实例并返回,而不是直接对原来的不可变对象的值 value 做 add 操作。
引用不是线程安全的!
记住,即使一个对象是不可变的因此这个对象是线程安全的,但这个对象的引用未必是线程安全的。看下面的例子:
public class Calculator { private ImmutableValue currentValue = null; public ImmutableValue getValue() { return currentValue; } public void setValue(ImmutableValue newValue) { this.currentValue = newValue; } public void add(int newValue) { this.currentValue = this.currentValue.add(newValue); } }
Calculator 类持有 ImmutableValue 类的实例的一个引用。注意,可以通过 setValue() 和 add() 方法来改变这个引用指向的对象。因此,即使 Calculator 类在内部使用了一个不可变的对象,但并不是说这个 Calculator 类就不可改变,它还是线程不安全的。换句话说, ImmutableValue 类是线程安全的,但使用了这个类的类未必也是线程安全的。这是通过不可变性来达到线程安全时需要注意的问题。
为了使 Calculator 类达到线程安全,可以在 getValue()、 setValue() 和 add() 方法前声明为 synchronized 方法。声明为 synchronized 方法消除了这个问题。
Next: Java 内存模型
- 线程安全和不可变性(Thread Safety and Immutability)
- 线程安全和资源共享(Thread Safety and Shared Resources)
- 可重入与线程安全(Reentrancy and Thread-Safety)
- ACE线程安全与同步(Thread Safety and Synchronization)
- ACE线程安全与同步(Thread Safety and Synchronization)
- 可重入与线程安全(Reentrancy and Thread-Safety)
- 10.线程安全和不可变性
- JavaScript中的不可变性(Immutability)
- 线程安全及不可变性
- 线程安全及不可变性
- 线程安全及不可变性
- 线程安全及不可变性
- 线程安全及不可变性
- 线程安全及不可变性
- 线程安全及不可变性
- 可重入性和线程安全性——Reentrancy and Thread-Safety
- 7 线程安全及不可变性
- 【java线程安全及不可变性】
- 基于ARM内核的LPC系列芯片技术文献及设计方案汇总
- vs如何连接连接sql server数据库?
- 插入排序java实现
- 社会实践mp4
- 一条进程的栈区、堆区、数据区和代码区在内存中的映射
- 线程安全和不可变性(Thread Safety and Immutability)
- 佳澜美白面膜晒后修复
- 秦皇岛小儿自闭症哪家yiyuan好
- Jackson 框架,轻易转换JSON
- linux下把普通文件链接到可执行文件中
- 消除ADB错误“more than one device and emulator”的方法
- centos7.0安装mysql5.7
- iftop使用说明
- 佳澜美白面膜使用步骤