1.重要的属性

1.1可见性

在没有同步的情况下,编译器和处理器会对代码的执行顺序进行重排。以提高效率。重排后的顺序是不可预知的,所以在多线程中无法对执行结果进行判断

看下面的代码

public class NoVisibility {

    private static boolean ready;

    private static int number;

    private static class ReaderThread extends Thread {
@Override
public void run() {
while (!ready) {
System.out.println(">>>");
}
System.out.println(1/number);
}
} public static void main(String[] args) {
new ReaderThread().start(); number = 1; ready = true;
} }

上面的执行结果可能会一直执行下去,也可能抛错。我们期望number=1以后,ready=true执行,最后输出1/1=1,由于重排,可能导致ready先初始化,然后线程读取到的还是ready=true,number=0.导致异常.



1.1.1 volatile
1.1.2 threadlocal
1.1.3

对象不可变的满足条件:

final修饰的List,Map等都是可以继续添加元素。可以采用Collections.unmodifiableXXX()。其实它的原理不过是实现一个Map接口。重写了put和remove等修改的时候进行异常抛出的操作。

    private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {
private static final long serialVersionUID = -1034234728574286014L; private final Map<? extends K, ? extends V> m; UnmodifiableMap(Map<? extends K, ? extends V> m) {
if (m==null)
throw new NullPointerException();
this.m = m;
} // 省略 public V put(K key, V value) {
throw new UnsupportedOperationException();
}
public V remove(Object key) {
throw new UnsupportedOperationException();
}
public void putAll(Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
}
05-11 14:43