多线程下的不可变性

多线程同时读写同一共享变量,存在并发问题。

那么如何解决并发安全问题。答案就是---不可变性。

就是对象被创建后,状态不再发生改变。对象的变量被赋值以后,不再发生改变,那么就不存在写操作,即状态得到了不变。

如何快速实现一个不可变类?

1.保证类修饰符为final,这样就不能被继承,不存在子类覆盖父类方法。

2.属性为final.

3.方法只能是只读的。

而在Java中很多包装器类都是不可变类,String,Double,Long,Short,Integer.那么不可变对象怎么提供修改功能呢?

答案是,往往不是修改本身的状态,而是重新创建一个新的不可变对象。

但是,解决某些问题,同时,也会带来某些问题,就是性能问题,重新创建对象带来内存空间的开销。那怎么去解决呢?

这些都是利用了设计模式里的享元模式。大家可以自己去搜索一下。

还有一个问题就是,不是不可变对象就能去做锁,因为利用了享元模式,所以,锁与被锁资源可能达不到控制的关系。可能用的是同一把锁。

还有最重要的一点,就是不可变类对象的属性,如果被修饰成了final,其实是可以被修该的,如果这个对象是基础对象,对象存在修改的方法,那么就得当心,这个不可变类的可能再多线程下存在问题。

并且不可变对象是线程安全,但是往往引用了不可变对象的引用不一定是安全的,往往存在,不可见性和原子性问题,不可见性问题可以加volatile修饰,原子性问题,可以利用原子类来实现。

猜你喜欢

转载自blog.csdn.net/weixin_39137699/article/details/93406375