JCIP_3_01_实践volatile

volatile实践

1volatile变量不会被缓存在寄存器或对其它处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。

2volatile只确保变量的可见性并不确保原子性,加锁机制既可确保可见性又可确保原子性。

3volatile变量对可见性的影响比volatile变量自身的特性更为重要。当线程A首先写入一个volatile变量并且线程B随后读取该变量时,在写入volatile变量之前对A可见的所有变量的值,在B读取了volatile变量后,对B也是可见的。

4、语句重排的问题,编译器和运行时检测到变量为volatile时是不会对该变量上的操作进行重排序(类似synchronized段)。

5volatile变量的适用场景

5.1、对变量的写入操作不依赖变量的当前值,或者能确保只有单个线程写变量的值。

5.2volatile变量不会与其它状态变量一起纳入不变性条件中。

5.3、当访问变量时不需要锁。

线程安全的正确性

某个类的行为与其规范完全一致,在良好的规范中通常会定义各种不变性条件来约束对象的状态,以及定义各种后验条件来描述对象操作的结果。

示例代码

这段代码的主要目的是实践一下volatile的不加锁读写特性,而对volatile变量不能保证操作的原子性则没能体现出来。

package org.ybygjy.jcip.chap3;


/**
 * 负责构造一个volatile多线程任务处理环境
 * <p>1.1、单写多读</p>
 * <p>1.2、没有锁</p>
 * <p>1.3、volatile确保变量的更新操作对其它线程可见</p>
 * <p>1.4、volatile变量不会缓存在寄存器或其它处理器不可见的地方</p>
 * <p>1.5、让人沉思的一句话(volatile变量对可见性的影响比volatile变量本身更为重要)</p>
 * 注意
 * <p>2.1、多线程读的问题,volatile只保证变量的更新操作在无需特殊同步的情况下对其它线程可见</p>
 * @author WangYanCheng
 * @version 2014-7-17
 */
public class VolatileThreadTest {
    public void doWork() {
        final VolatileVO volatileVO = new VolatileVO();
        VolatileWriteThread writeThread = new VolatileWriteThread(volatileVO);
        VolatileReadThread readThread1 = new VolatileReadThread(volatileVO);
        VolatileReadThread readThread2 = new VolatileReadThread(volatileVO);
        writeThread.start();
        readThread1.start();
        readThread2.start();
    }
    /**
     * 测试入口
     * @param args 参数列表
     */
    public static void main(String[] args) {
        VolatileThreadTest volatileThreadTest = new VolatileThreadTest();
        volatileThreadTest.doWork();
    }
    /**
     * 负责{@link VolatileVO} 写操作
     * @author WangYanCheng
     * @version 2014-7-17
     */
    class VolatileWriteThread extends Thread {
        private VolatileVO volatileVo;
        public VolatileWriteThread(VolatileVO volatileVO) {
            this.volatileVo = volatileVO;
        }
        @Override
        public void run() {
            while (true) {
                int i = volatileVo.getStep() + 1;
                this.volatileVo.setStep(i);
                if (i%500 == 0) {
                    break;
                }
                try {
                    sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * 负责{@link VolatileVO} 读操作
     * @author WangYanCheng
     * @version 2014-7-17
     */
    class VolatileReadThread extends Thread {
        private VolatileVO volatileVo;
        public VolatileReadThread(VolatileVO volatileVo) {
            this.volatileVo = volatileVo;
        }

        @Override
        public void run() {
            while (true) {
                String tmpValue = getName() + "#" + volatileVo.getStep();
                System.out.println(tmpValue);
                if (volatileVo.getStep()%500==0) {
                    break;
                }
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
/**
 * 定义数据实体
 * @author WangYanCheng
 * @version 2014-7-17
 */
class VolatileVO {
	/** 使用volatile确保并发环境下值的可见性*/
    private volatile int step;

    public int getStep() {
        return step;
    }

    public void setStep(int step) {
        this.step = step;
    }
}

参考资料

1Java Concurrenty In Practice


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值