Integer String 对象作为锁的注意事项

 

Integer vs int

由一个多线程共享Integer类变量问题引起的。。。

中,解释了为什么锁不住Integer对象,本次我们做一些实践

import java.util.Date;

/**
 * https://www.cnblogs.com/silyvin/p/11475233.html
 * Created by sunyuming on 19/8/28.
 */
public class MultiLock {

    public Integer lockInteger;
    public String lockString;
    public String lockStringNew;

    public static void main(String [] f) throws InterruptedException {
        MultiLock a = new MultiLock();
        MultiLock b = new MultiLock();
        a.lockInteger = 127;
        b.lockInteger = 127;
        a.lockString = "abc";
        b.lockString = "abc";
        a.lockStringNew = new String("abc");
        b.lockStringNew = new String("abc");

        System.out.println("
当127自动装箱Integer时");
        new Thread(new MyThreadInteger(a)).start();
        new Thread(new MyThreadInteger(b)).start();

        Thread.sleep(10000);
        a.lockInteger = 128;
        b.lockInteger = 128;
        System.out.println("
当128自动装箱Integer时");
        new Thread(new MyThreadInteger(a)).start();
        new Thread(new MyThreadInteger(b)).start();

        Thread.sleep(10000);
        a.lockInteger = new Integer(127);
        b.lockInteger = new Integer(127);
        System.out.println("
当Integer堆时");
        new Thread(new MyThreadInteger(a)).start();
        new Thread(new MyThreadInteger(b)).start();

        Thread.sleep(10000);
        System.out.println("
当String常量池装箱时");
        new Thread(new MyThreadString(a)).start();
        new Thread(new MyThreadString(b)).start();

        Thread.sleep(10000);
        System.out.println("
当String堆时");
        new Thread(new MyThreadStringNew(a)).start();
        new Thread(new MyThreadStringNew(b)).start();

        Thread.sleep(10000);
        System.out.println("
当String堆intern时");
        new Thread(new MyThreadStringNewIntern(a)).start();
        new Thread(new MyThreadStringNewIntern(b)).start();

    }

    public void testIntegerLock() {
        System.out.println("testIntegerLock" + System.identityHashCode(lockInteger));
        synchronized (lockInteger) {
            try {
                System.out.println("starttestIntegerLock" + new Date());
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void testStringLock() {
        System.out.println("testStringLock" + System.identityHashCode(lockString));
        synchronized (lockString) {
            try {
                System.out.println("starttestStringLock"+ new Date());
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void testStringNewLock() {
        System.out.println("testStringNewLock" + System.identityHashCode(lockStringNew));
        synchronized (lockStringNew) {
            try {
                System.out.println("starttestStringNewLock"+ new Date());
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void testStringNewInternLock() {
        System.out.println("testStringNewInternLock" + System.identityHashCode(lockStringNew.intern()));
        synchronized (lockStringNew.intern()) {
            try {
                System.out.println("starttestStringNewInternLock"+ new Date());
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static class MyThreadInteger implements Runnable {

        private MultiLock multiLock;
        public MyThreadInteger(MultiLock multiLock) {
            this.multiLock = multiLock;
        }

        @Override
        public void run() {
            this.multiLock.testIntegerLock();
        }
    }

    public static class MyThreadString implements Runnable {

        private MultiLock multiLock;
        public MyThreadString(MultiLock multiLock) {
            this.multiLock = multiLock;
        }

        @Override
        public void run() {
            this.multiLock.testStringLock();
        }
    }

    public static class MyThreadStringNew implements Runnable {

        private MultiLock multiLock;
        public MyThreadStringNew(MultiLock multiLock) {
            this.multiLock = multiLock;
        }

        @Override
        public void run() {
            this.multiLock.testStringNewLock();
        }
    }

    public static class MyThreadStringNewIntern implements Runnable {

        private MultiLock multiLock;
        public MyThreadStringNewIntern(MultiLock multiLock) {
            this.multiLock = multiLock;
        }

        @Override
        public void run() {
            this.multiLock.testStringNewInternLock();
        }
    }
}

当127自动装箱Integer时
testIntegerLock1842818263
testIntegerLock1842818263
starttestIntegerLockWed Dec 11 11:52:04 CST 2019
starttestIntegerLockWed Dec 11 11:52:09 CST 2019

当128自动装箱Integer时
testIntegerLock2025391892
testIntegerLock755079750
starttestIntegerLockWed Dec 11 11:52:14 CST 2019
starttestIntegerLockWed Dec 11 11:52:14 CST 2019

当Integer堆时
testIntegerLock455290755
testIntegerLock2078391126
starttestIntegerLockWed Dec 11 11:52:24 CST 2019
starttestIntegerLockWed Dec 11 11:52:24 CST 2019

当String常量池装箱时
testStringLock440496836
starttestStringLockWed Dec 11 11:52:34 CST 2019
testStringLock440496836
starttestStringLockWed Dec 11 11:52:39 CST 2019

当String堆时
testStringNewLock835411425
testStringNewLock872854004
starttestStringNewLockWed Dec 11 11:52:44 CST 2019
starttestStringNewLockWed Dec 11 11:52:44 CST 2019

当String堆intern时
testStringNewInternLock440496836
testStringNewInternLock440496836
starttestStringNewInternLockWed Dec 11 11:52:54 CST 2019
starttestStringNewInternLockWed Dec 11 11:52:59 CST 2019

Process finished with exit code 0

装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的。

在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。

a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,便调用Integer.valueOf方法

https://www.cnblogs.com/dolphin0520/p/3780005.html

原文地址:https://www.cnblogs.com/silyvin/p/11475233.html