不变性

不可变对象一定是线程安全的

那么什么是不可变对象呢?

当满足一下条件时,对象才是不可变的。

  • 对象创建以后其状态就不能修改
  • 对象的所有域都是final类型
  • 对象是正确创建的(在对象的创建期间,this引用没有逸出)

我们回到之前因数分解的例子,通过构造一个不可变类来实现同步:

class OneValueCache{
    private final BigInteger lastNumber;
    private final BigInteger[] lastFactors;

    public OneValueCache(BigInteger i, BigInteger[] factors){
        lastNumber = i;
        lastFactors = Arrays.copyOf(factors, factors.length);
    }

    public BigInteger[] getFactors(BigInteger i){
        if (lastNumber == null || !lastNumber.equals(i)) {
            return null;
        } else {
            return Arrays.copyOf(lastFactors, lastFactors.length);
        }
    }
}

public class VolatileCachedFactorizer implements Servlet{
    private volatile OneValueCache cache = 
        new OneValueCache(null,null);

    public void service(ServletRequest req, ServletResponse resp){
        BigInteger i = extractFromRequest(req);
        BigInteger[] factors = cache.getFactors(i);
        if (factors == null) {
            factors = factor(i);
            cache = new OneValueCache(i, value);
        }
        encodeIntoResponse(resp, factors); 
    }
}

我们可以看到OneValueCache为一个不可变类,并且我们在创建时,使用volatile关键字声明,这样保证了线程安全性和可见性。

但要注意的一点是:
如果final类型的域所指向的是可变对象,那么在访问这些域所指向的对象的状态时仍然需要同步

public final class ThreeStooges {
  private final Set<String> stooges = new HashSet<String>();

  public ThreeStooges() {
    stooges.add("Moe");
    stooges.add("Larry");
    stooges.add("Curly");
  }

  public boolean isStooge(String name) {
    return stooges.contains(name);
  }

  public synchronized Set<String> getStooges(){
    return stooges;
  }
}

如上,stooges变量为可变对象,因此,如果我们需要对其访问时,需要加上synchronized关键字来保证同步。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,730评论 0 11
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,839评论 18 399
  • 可见性 当一个线程修改了对象状态后,其他线程能够看到发生的状态变化 如何保证? 加锁,当线程B执行由锁保护的同步代...
    Cafebaby阅读 603评论 0 2
  • 几年前开始看塔莎奶奶的书,并深深的被她的生活方式所吸引,今日再读她的传家宝,又添佩服之情…… 且罗列下...
    aqiao阅读 652评论 1 1
  • 对腾讯火热推出的微信小程序进行超快的入门,快速掌握微信小程序的入门及基础知识学习技巧,并带您搞定一个网络博客小程序!
    小波yagamis阅读 419评论 0 0