多线程-- 四.不可变对象和线程封闭带来的线程安全

不可变对象和线程封闭带来的线程安全

 

不可变对象

 

当一个类的对象满足下面条件时,这个对象可以成为不可变对象

    通过在某些情况下,将不会修改的类对象设计为不可变对象,来让对象成为线程安全的.把对象编程不可变对象,就不会出现线程安全问题了

1.对象创建以后,其状态就不能更改.

2.对象所有域都是final类型.

3.对象是正确创建的(在对象创建期间,this引用没有逸出).

 

 

变为不可变对象方法:

 

1.final关键字修饰

修饰类,类不可以被继承.

修饰方法,方法不可以被重写.

修饰基本数据类型,不可以更改值.

修饰引用数据类型,不可以指向新的地址,但是可以更改值.(也可以更改,见方法2)

 

2.Collections.unmodifiableXXX()方法  XXX:List,Set,Map…..

用这个方法修饰的对象,就不可以被更改了

这样,map里面修改值也不可以了,直接报错.其实put方法是可以执行的,只是直接抛异常了.

这是因为这个方法源码里面,它返回一个自定义的map,这个map里面就是把修改的一些方法,直接写为了抛异常.

 

3.google的Guava包中的方法ImmutableXXX  XXX:List,Set,Map…..

这个跟上面的基本类似,也是直接报错,并且方法上也提示了横线

 

 


 

线程封闭

 

线程封闭的几种方式:

1.Ad-hoc线程封闭:程序控制实现,最糟糕,忽略,不建议使用.

2.堆栈封闭:局部变量,无并发问题.(这个其实也是我们经常用的,说白了,就是能用局部变量的,就不用全局变量.全局变量会产生线程问题.)

3.ThreaLocal线程封闭:特别好的封闭方法

 

 

创建ThreadLocal对象:

    ThreadLocal<> requestHolder = new ThreadLocal<>();

ThreadLocal类提供的几个方法:

    public T get() { }:    get()方法是用来获取ThreadLocal在当前线程中保存的变量副本.

    public void set(T value) { }:    set()用来设置当前线程中变量的副本.

    public void remove() { }:    remove()用来移除当前线程中变量的副本.

    protected T initialValue() { }:     initialValue()是一个protected方法,一般是用来在使用时进行重写的.

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值