zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    POJ 3411 Paid Roads(DFS)
    POJ 1699 Best Sequence(DFS)
    Codeforces Round #191 (Div. 2)
    Windows && Linux 搭建python开发环境
    zabbix 源码编译安装
    智能运维基础设施
    Redis
    ubuntu16.04 安装 mysql
    Python必须知道的基础语法
    ubuntu && CentOS && RedHat 离线安装docker
  • 原文地址:https://www.cnblogs.com/silyvin/p/11475233.html
Copyright © 2011-2022 走看看