[并发]Immutable 不变模式

Immutable不变模式

并发问题是由于不同线程共同操作共享内存,导致读写顺序错乱,影响了共享内存的值。

那么,如果线程只读操作共享内存,就不存在并发问题了。

1. 如何实现不变性

第一,需要类本身是final的,防止子类继承他而修改不变性。

第二,需要类的属性都是final的,并且只存在读方法。

第三,使用深拷贝修改对象,简单说就是在修改对象时,new一个新的对象返回。但是一方面考虑麻烦,另一方面clone方法是native方法,效率更高,一般我们还是选择使用clone方法实现。

Java中有一个很好的例子,就是String类。请移步-> https://blog.csdn.net/sougou_1323/article/details/103223855

2. 享元模式

简单说,享元模式就是创建缓存,Java中的包装类除了Float和Double都有缓存。请移步 2. 3)-> https://blog.csdn.net/sougou_1323/article/details/103227907

这里需要注意一点,请不要使用包装类型作为锁,如下面的栗子,al和bl看上去是两个锁,实际上是一个锁,这样很容易出问题。

class A {
  Integer al = Integer.valueOf(1);
  public void setA() {
    synchronized (al) {
      // ...
    }
  }
}
class B {
  Integer bl = Integer.valueOf(1);
  public void setB() {
    synchronized (bl) {
      // ...
    }
  }
}

3. 假不变性

假?请看下面的栗子。这里的问题本质是,Java中都是引用,user引用是final的,但是User对象不是final的。换句话说,user的引用确实不可变,但是user实例的内容是可变的。所以在使用不变性模式的时候一定要确认是否要求属性对象也具备不可变性。

public final class Shop{
  private final User user;
  public Account(User user){
    this.user = user;
  }
  public User getUser(){
    return this.user;
  }
}

public class User {
  private String name;
  private Integer age;
  public void addAge() {
    age += 1;
  }
}

还有一种方法,将getUser方法配合不变性,不将Shop的属性user返回,而是将User复制一份返回。这样不管外界拿到user怎么折腾都不会影响到Shop的属性user,也就保证了不变性,但是这种实现方式比较消耗内存,可能会引起频繁的GC,具体还要看实际情况来决定。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值