线程安全的问题

当设计线程安全的类时,良好的面向对象技术、不可修改性,以及明晰的不可变性规范都能起到一定的帮助作用。

关于线程安全

线程安全就是当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步和协同,这个类都能表现出正确的行为,那么这个类就是线程安全的。

可以在线程安全的类中安装同步机制,这样调用的时候就不需要相应的同步机制了。

另外无状态的对象一定是线程安全的。

原子性

竞态条件

发生静态条件的常见方式是先检查后执行,其实就是相互操作一个对象而已。比如延时实例化的例子

public Person getPerson() {
  if(this.person==null) {
    this.person = new Person();
  }
  return this.person;
}

还有类似的计数+1等等。

复合操作

这在操作系统中应该称为临界区。

原子类

在java.util.concurrent.atomic包中包含了一些原子变量类。这些类上的操作都是线程安全型的。

加锁机制

内置锁

synchronized (lock) {
  ...临界区
}

其他线程调用时会阻塞。

锁重入

如果一个线程访问一个另一个线程占用的锁,是不能通过的。但是一个线程访问它自己占用的锁是可以操作的。重入意味着锁操作的颗粒度是“线程”。

用锁保护状态

每个共享的可变变量都应该只由一个锁来保护,从而使维护人员知道是哪一个锁。通常将锁放入类的内部。

对于每个包含多个变量的不变性条件,其中涉及的所有变量都需要同一个锁来保护。

活跃性和性能

可使用缓存的策略。另外同步块范围太大也会影响并发,所以可以尽量减少同步块的范围。

在执行时间较长的代码块上,千万不要加上锁。

results matching ""

    No results matching ""