多线程 - volatile

来源:互联网 发布:9月2非农数据 编辑:程序博客网 时间:2024/06/05 17:56

1 . volatile 简述

 volatile 可以认为是程度较轻的synchronized,volatile编码较少,并且运行时,效率较高,但它只是synchronized功能的一部分。

volatile 禁止指令重排,且将修改后的数据,立即从工作内存中刷新到主内存中。

缺点:

volatile变量是轻量级的同步机制,因为在使用这些变量时不会发生上下文切换或者线程调度等操作。然而,volatile变量同样存在一些局限性:虽然它提供了相似的可见性保证操作,但不能用于构建原子的复合操作。因此,当一个变量依赖于其他变量时,或者变量的新值依赖与旧值时,就不能使用volatile变量;计算器或者互斥体就不能使用。


2. volatile 与 synchronized 对比

性能上比较:volatile 性能更优

volatile 不持有对象锁,synchronized持有对象锁

volatile并发执行,synchronized 顺序执行

volatile 通过禁止指令重排,synchronized通过只有一个线程执行,单线程不存在指令重排


3. volatile 的使用条件

正确使用volatile要满足两个条件:

对变量的写操作,不依赖于当前值,如:计数器就不适用volatile

该变量没有包含在具有其他变量的不变式中

public class Stack {public static void main(String[] args) {Sum sum = new Sum();ThreadTest1 s = new ThreadTest1(sum);for (int i = 0; i < 1000; i++) {new Thread(s).start();}System.out.println(sum.sum);}}class ThreadTest1 implements Runnable {private Sum sum;public ThreadTest1(Sum sum) {this.sum = sum;}public void run() {sum.setSum();}}class ThreadTest2 implements Runnable {private Sum sum;public ThreadTest2(Sum sum) {this.sum = sum;}public void run() {sum.getSum();}}class Sum {public volatile Integer sum = 0;public void setSum() {sum++;System.out.println(sum);}public Integer getSum() {return sum;}}

</pre><p></p><p></p><p>4. volatile 使用场景</p><p><span style="white-space:pre"></span>4.1 状态标记</p><p><pre name="code" class="java">public class State {private volatile boolean state = true;public void shutdown() {this.state = false;}public void doSomething() {if (state) {System.out.println(Thread.currentThread().getName()+ ": I'm running");}}public static void main(String[] args) {State s = new State();for (int i = 0; i < 10; i++) {new Thread(new Thread2(s)).start();if (i == 2) {new Thread(new Thread1(s)).start();}}}}class Thread1 implements Runnable {private State state;public Thread1(State state) {this.state = state;}public void run() {state.shutdown();}}class Thread2 implements Runnable {private State state;public Thread2(State state) {this.state = state;}public void run() {state.doSomething();}}


4.2 独立观察

 此种情况是只有一个线程对数据进行修改,多个线程读取修改后的值。

例如,天气情况,一个线程修改当前的天气情况,其他线程读取天气信息。

4.3 volatile与synchronized的读写锁使用,提高效率

public class ReadWrite {volatile int value = 0;public int getValue() {return value;}public synchronized void increment() {value++;}}

4.4 单例模式,双重锁检查

public class Singleton {volatile private static Singleton singleton;private Singleton() {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}public static Singleton getInstance() {if (singleton == null) {synchronized (Singleton.class) {if (singleton == null) {singleton = new Singleton();}}}return singleton;}public static void main(String[] args) {for (int i = 0; i < 10; i++) {new Thread(new ThreadTest()).start();}}}class ThreadTest implements Runnable {public void run() {Singleton s = Singleton.getInstance();System.out.println(s);}}

参考资料

IBM: http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

《java并发编程实战》




IBM: http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
0 0