java 并发安全的思考

保证并发安全性的方式有三种:不共享、不可变、同步。

不共享——线程封闭

线程封闭(thread confinement):数据在单线程中进行访问,不需要同步策略。

当某个对象封闭在一个线程中时,这种用法将自动实现线程安全,即使被封闭的对象本身不是线程安全的

Ad-hoc线程封闭

Ad-hoc线程封闭是指,维护线程封闭性的职责完全由程序来实现。没有任何一种语言特性,能够将对象封闭到目标线程上。

在volatile变量上存在一种特殊的线程封闭,只要你确保只有单个线程对共享的volatile变量执行写入操作,那个就可以安全地在这些共享的volatile变量上执行”读取-修改-写入”的操作。

栈封闭

位于执行线程的栈中,其他线程无法访问这个栈。局部变量的固有属性之一就是封闭在执行线程中。

  • 基本类型的局部变量,由于任何方法都无法获得对基本类型的引用,所以不会破坏栈封闭性。
  • 引用类型,必须确保不会发布该引用类型。
public int loadTheArk(Collection<Animal> candidates) {
    SortedSet<Animal> animals;
    int numPairs = 0;
    Animal candidate = null;
   //保存对象的引用animals变量被封闭在方法中
    animals = new TreeSet<Animal>(new SpeciesGenderComparator());
    animals.addAll(candidates);
    for(Animal a : animals) {
        if (candidates == null || !candidate.isPotentialMate(a))
            candidate = a
        else{
            ark.load(new AnimalPair(candidate, a));
            ++numPairs;
            candidate = null
        }
    }
    return numPairs;
}

ThreadLocal类

通常使用ThreadLocal保证可变的单例变量(Singletion)或全局变量进行共享。

例如,在单线程应用程序中可能会维持一个全局的数据库连接,并在程序启动时初始化这个连接对象,从而避免在调用每个方法时都要传递一个Connection对象。

public int loadTheArk(Collection<Animal> candidates) {
    SortedSet<Animal> animals;
    int numPairs = 0;
    Animal candidate = null;

    animals = new TreeSet<Animal>(new SpeciesGenderComparator());
    animals.addAll(candidates);
    for(Animal a : animals) {
        if (candidates == null || !candidate.isPotentialMate(a))
            candidate = a
        else{
            ark.load(new AnimalPair(candidate, a));
            ++numPairs;
            candidate = null
        }
    }
    return numPairs;
}

不可变——不变性

如果某个对象在被创建后其状态就不能被修改,那么这个对象就称为不可变对象。线程安全性是不可变对象的固有属性之一。

满足以下条件,对象才是不可变的:

  • 对象创建以后其状态就不能修改。
  • 对象的所有域都是final类型。
  • 对象在创建期间,this引用没有逸出。
@Immutables
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)
    }
}

同步

同步是指通过同步策略访问共享的变量(锁、信号量等)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值