您的位置:首页 > 编程语言 > Java开发

java并发编程实战:对象的共享笔记

2017-11-22 09:22 239 查看

可见性

volatile关键字:

http://www.cnblogs.com/paddix/p/5428507.html

volatile关键字的两层语义:

- 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

- 禁止进行指令重排序。

volatile只能保证对单次读/写的原子性

volatile不能保证 i++ 这种的原子性。

使用场景:

双重检查(DCL)单例

package com.paddx.test.concurrent;

public class Singleton {
public static volatile Singleton singleton;

/**
* 构造函数私有,禁止外部实例化
*/
private Singleton() {};

public static Singleton getInstance() {
if (singleton == null) {
synchronized (singleton) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}


现在我们分析一下为什么要在变量singleton之间加上volatile关键字。要理解这个问题,先要了解对象的构造过程,实例化一个对象其实可以分为三个步骤:

- (1)分配内存空间。

- (2)初始化对象。

- (3)将内存空间的地址赋值给对应的引用。

但是由于操作系统可以对指令进行重排序,所以上面的过程也可能会变成如下过程:

- (1)分配内存空间。

- (2)将内存空间的地址赋值给对应的引用。

- (3)初始化对象

  如果是这个流程,多线程环境下就可能将一个未初始化的对象引用暴露出来,从而导致不可预料的结果。因此,为了防止这个过程的重排序,我们需要将变量设置为volatile类型的变量。

  

状态标记量

volatile boolean inited = false;
//线程1:
context = loadContext();
inited = true;

//线程2:
while(!inited ){
sleep()
}
doSomethingwithconfig(context);


http://www.importnew.com/18126.html

发布与逸出

发布:使对象能够在除当前作用域之外的地方使用。

- 将对象的引用存储到公共静态域。

- 在非私有方法中返回引用。

- 不要在构造过程中使this引用逸出。

**构造方法使用匿名内部类会产生溢出。**


使用工厂方法来防止。

溢出:指某个对象不应该发布却被发布了。

线程封闭

多线程访问共享数据时,通常需要同步,一种避免使用同步的方式就是不共享数据。如果仅在单线程里访问数据,那么就不需要使用同步,这种技术被称为线程封闭。

栈封闭

局部变量访问对象。

ThreadLocal

http://blog.csdn.net/cauchyweierstrass/article/details/48001521

不变性

不可变对象一定是线程安全的。

对于如何构建一个不可变对象,我们有三个条件(虽然说是”条件”,但并不是那么硬性的,可以算是某种建议):

- 对象创建后保证状态不可变

- 对象的所有field都是final

- 创建期间没有逸出自身引用(this引用逸出),保证对象的创建正确。

https://www.cnblogs.com/Kavlez/p/4041395.html

不可变对象与初始化安全性

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: