synchronized锁对象为包装类型(修饰变量)

synchronized锁对象为包装类型时,需要考虑包装类型的缓存,如Integer默认缓存-127~128之间的数值,所以下例中锁a和锁b实际锁的是同一个对象;另外其它包装类也需要注意类似问题(如Byte/Short);

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

public static Short valueOf(short s) {
    final int offset = 128;
    int sAsInt = s;
    if (sAsInt >= -128 && sAsInt <= 127) { // must cache
        return ShortCache.cache[sAsInt + offset];
    }
    return new Short(s);
}
public class ConcurrentTest {
    private Integer a = 100;
    private Integer b = 100;

    public static void main(String[] args) throws InterruptedException {
        ConcurrentTest test = new ConcurrentTest();
        test.testA();
        test.testB();
        System.err.println("a:"+ test.a);
        System.err.println("b:"+ test.b);
    }

    private void testA() {
        new Thread(() -> {
            System.err.println("A thread started");
            synchronized (a) {
                for (int i = 0; i < 10; i++) {
                    System.err.println("a =>");
                    sleep(1);
                }
            }
        }).start();
    }

    private void testB() {
        new Thread(() -> {
            System.err.println("B thread started");
            synchronized (b){
                for (int i = 0; i < 10; i++) {
                    System.err.println("b =>");
                    sleep(1);
                }
            }
        }).start();
    }
}
out==> //实际输出是等打印完a才打印b
A thread started
a =>
B thread started
a =>
a =>
a =>
a =>
a =>
a =>
a =>
a =>
a =>
b =>
b =>
b =>
b =>
b =>

当然实际开发过程中一般也不会使用包装类做锁对象!

results matching ""

    No results matching ""