(一)java多线程编程设计模式之不可变模式

                                 Immutable Object模式

(一)Immutable Object模式

在多线程环境中,一个对象通常会被多的线程共享,如果存在多个线程并发地修改该对象的状态或者一个线程访问该对象的状态而其他线程想要修改该对象的状态,就会出错。因此通常情况下,我们就会对这个对象加锁。加锁显然会有额外的开销,因此,我们可以使用Immutable Object模式來代替加锁的效果。

Immutable Object模式通过使用内容对外可见,但是状态不可变的对象使得被共享对象天生线程安全。

(二)举个��

假设我们用一个数组存储了一个同学的成绩。

	Arraylist gradle

现在有两个线程,一个线程更新每一个学期,该同学的成绩,一个线程则是获取该同学的平均分。如果不加锁,可能在更新成绩到一半的时候,另一个线程则过来计算平均分,这时gradle中有的科目是旧的成绩,有的是新的成绩,这时就会得出错误的平均分。

解决方式:Immuatable Object模式

public final class gradleList{
  private volatitle Arraylist gradle;
   public gradleList(){
     获取成绩 ,赋值list
  }
  public static list getGradle() {
   return gradle;  
}

}
public class student {
    private gradlist list;
    public void setList(gradlist list) {
    	this.list = list;
    }
    
    public gradlist getList() {
    	return list;
    }

}
     其中gradleList是不可变对象,只有get方法。这就决定了每次gradleList都是new出来的,而不是改变其中的变量获得的。

(三)使用场景

Immutable Object方法每次更新都要new一个不可变量出来,因此如果更新太频繁,那么资源耗用太大,不可取。在上个例子中,学生的成绩每个学期更新一次,所以比较适用。此外HashMap的key值变化会导致hashcode变化,因此我们通常使用string作为key值。这也是一种不可变对象。使用不可变对象作为key值是非常好的。

(四)类图


(五)源码

CopyOnWriteArrayList
CopyOnWriteArrayList是线程安全的,它就是使用了不可变对象模式。
 public synchronized void add(int index, E e) {
        Object[] newElements = new Object[elements.length + 1];
        System.arraycopy(elements, 0, newElements, 0, index);
        newElements[index] = e;
        System.arraycopy(elements, index, newElements, index + 1, elements.length - index);
        elements = newElements;
    }
     这里的synchronized 用于修饰add方法,避免同时添加。而其中存储的对象则是使用了不可变对象模式,每次add时会新建newElements并将所有数据存进去,新加的对象存在最后一个。因此 CopyOnWriteArrayList消耗很大,不适合频繁使用。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值