JAVA多线程并发工具之Threadlocal和volatitle

众所周知,要进行多线程开发必须要先熟悉JAVA并发工具包,工欲善其事必先利其器,下面讨论一下ThreadLocal和volatile的可见性问题!

java.lang.ThreadLocal:
Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive;
根据JDK中的解释,ThreadLocal为每个线程维护一份本地变量的副本,只要这个线程是alive,这份副本就一直存在;
volatile是JAVA中的关键字,volatile修饰的变量都会被同步到主存中,根据内存模型理解,同步到主存中也就意味这对其他的线程是可见的;
接下来抛出问题:
  如果一个对象Obj是被ThreadLocal维护的,Obj中有一个volatile修饰的成员变量variable,那么variable对于其他线程是可见的吗?

接下来上代码:

对象Obj

/**
 * @author wuhuagang
 * @date 2019/1/3
 * @desc
 */
public class Dto {
    private volatile ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

    public ByteArrayOutputStream getByteArrayOutputStream() {
        return byteArrayOutputStream;
    }

    public void setByteArrayOutputStream(ByteArrayOutputStream byteArrayOutputStream) {
        this.byteArrayOutputStream = byteArrayOutputStream;
    }
}

主程维护ThreadLocal

/**
 * @author wuhuagang
 * @date 2019/1/3
 * @desc
 */
public class MainProgram {
    public static ThreadLocal<Dto> threadLocal = new ThreadLocal<>();
    public static void main(String[] args) throws Exception {
        Dto dto = new Dto();
        threadLocal.set(dto);
        ThreadMain threadMain = new ThreadMain();
        threadMain.start();
        for(int i = 0;i<100;i++){
            dto.getByteArrayOutputStream().write("中国人民很行:".concat(Integer.valueOf(i).toString()).getBytes());
        }
    }
}
起一个线程去试试成员变量的可见性
/**
 * @author wuhuagang
 * @date 2019/1/3
 * @desc
 */
public class ThreadMain extends Thread{
    @Override
    public void run() {
        Dto dto = MainProgram.threadLocal.get();
        while (dto!=null){
            System.out.println("content:"+dto.getByteArrayOutputStream().toString());
        }
    }
}

结果:

content:中国人民很行:0中国人民很行:1中国人民很行:2中国人民很行:3中国人民很行:4中国人民很行:5  。。。

结果说明,volatile修饰的变量,即使变量存储在ThreadLocal的本地副本中,依然会被volatile同步到主存中,对其他线程可见,所以小伙伴们记住,这样的代码,即使是threadlocal结构的也会是产生安全问题的!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值