• Java synchronized锁 String 和 Integer 会有什么问题?


    一. 问题

    1. synchronized 锁String, 非final , 如果String的value值改变了会怎么样.

    2. synchronized 锁Integer, 非final, 如果Integer 值都是1 , 多个线程并发会怎么样.

    3. synchronized 锁Integer, 非final, 如果Integer 值都是128 , 多个线程并发会怎么样.

    二. 答案

    1. synchronized 锁String , 如果String的value值改变了会怎么样.

    String 值改变的话, 原有的锁依旧处于加锁状态. 新的线程在申请锁的时候, 会加载到新的String 值. 导致锁失效, 新的线程依旧会执行.

    1. synchronized 锁两个Integer类型的lock, 每个lock有自己的线程, 如果Integer 值都是1 , 多个线程并发会怎么样.

    因为Integer类中有缓存 -128 到 127 , 如果值相同, 会导致所有的线程阻塞, 顺序执行.

    1. synchronized 锁Integer, 非final, 如果Integer 值都是128 , 多个线程并发会怎么样.

    如果锁的值 超出 -128 ~127 的范围. 并发执行.

    三. 代码验证

    3.1. String类型

    
    /**
     * 验证锁启动顺序,
     * 当变更lock的时候, 会有两个线程同时存在.
     */
    public class lockString01 {
        private static String lock = "lock";
    
        public static void main(String[] args) throws Exception {
    
            doRun("t1");
            doRun("t2");
            doRun("t3");
            doRun("t4");
            doRun("t5");
    
    //        System.out.println("chang lock.....");
            lock = "new lock";
    //        System.out.println("chang lock.....");
            doRun("t6");
            doRun("t7");
    //        while (true) {
    //            lock = UUID.randomUUID().toString();
    //            try {
    //                TimeUnit.SECONDS.sleep(1L);
    //            } catch (InterruptedException e) {
    //                e.printStackTrace();
    //            }
    //        }
        }
    
        private static void doRun(String name) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lock) {
                        System.out.println("thread: " + name + " start");
                        try {
                            System.out.println("thread: " + name + " sleep. lock is :" + lock);
                            TimeUnit.SECONDS.sleep(5L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("thread: " + name + " end");
                    }
                }
            }).start();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    
    /**
     * 验证锁变换, 是否是顺序加锁. 目前看是,存在并发
     */
    public class lockString02 {
        private static String lock = "lock";
    
        public static void main(String[] args) throws Exception {
    
            doRun("t1");
            doRun("t2");
            doRun("t3");
            doRun("t4");
            doRun("t5");
            doRun("t6");
            doRun("t7");
            while (true) {
                lock = UUID.randomUUID().toString();
            }
        }
    
        private static void doRun(String name) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lock) {
                        System.out.println("thread: " + name + " start");
                        try {
                            System.out.println("thread: " + name + " sleep. lock is :" + lock);
                            TimeUnit.SECONDS.sleep(5L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("thread: " + name + " end");
                    }
                }
            }).start();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    
    /**
     * 锁随机变换.
     * 每个线程休眠5s, 阻塞1s再去加载下一个线程.
     * 验证结果:
     *  锁失效了, 存在并发, 线程会有并发执行.
     *
     */
    public class lockString03 {
        private static String lock = "lock";
    
        public static void main(String[] args) throws Exception {
    
            doRun("t1");
            doRun("t2");
            doRun("t3");
            doRun("t4");
            doRun("t5");
            doRun("t6");
            doRun("t7");
            while (true) {
                lock = UUID.randomUUID().toString();
            }
        }
    
        private static void doRun(String name) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lock) {
                        System.out.println("thread: " + name + " start");
                        try {
                            System.out.println("thread: " + name + " sleep. lock is :" + lock);
                            TimeUnit.SECONDS.sleep(5L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("thread: " + name + " end");
                    }
                }
            }).start();
            try {
                System.out.println("thread: " + name + " block 1 s.");
                TimeUnit.SECONDS.sleep(1L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    3.2. Integer类型

    
    /**
     * 验证锁变换, 是否是顺序加锁. 目前看是,存在并发
     */
    public class lockInteger01 {
        private static Integer lock = 1;
    
        public static void main(String[] args) throws Exception {
    
            doRun("t1");
            doRun("t2");
            doRun("t3");
            doRun("t4");
            doRun("t5");
    
    
            lock = 2;
            doRun("t6");
            doRun("t7");
    //        while (true) {
    //            lock = UUID.randomUUID().toString();
    //            try {
    //                TimeUnit.SECONDS.sleep(1L);
    //            } catch (InterruptedException e) {
    //                e.printStackTrace();
    //            }
    //        }
        }
    
        private static void doRun(String name) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lock) {
                        System.out.println("thread: " + name + " start");
                        try {
                            System.out.println("thread: " + name + " sleep. lock is :" + lock);
                            TimeUnit.SECONDS.sleep(5L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("thread: " + name + " end");
                    }
                }
            }).start();
        }
    
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    
    /**
     * 验证锁变换, 是否是顺序加锁. 目前看是,存在并发
     */
    public class lockInteger02 {
        private static Integer lock = 1;
    
        public static void main(String[] args) throws Exception {
    
            doRun("t1");
            doRun("t2");
            lock = 2;
            doRun("t3");
            doRun("t4");
            doRun("t5");
            doRun("t6");
            doRun("t7");
            while (true) {
                lock = new Random().nextInt();
            }
        }
    
        private static void doRun(String name) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lock) {
                        System.out.println("thread: " + name + " start");
                        try {
                            System.out.println("thread: " + name + " sleep. lock is :" + lock);
                            TimeUnit.SECONDS.sleep(5L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("thread: " + name + " end");
                    }
                }
            }).start();
        }
    
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    
    /**
     * 验证Integer值为1, 两个锁. 多个线程会不会并发执行
     * 结果: 不会并发线程, 所以使用Integer 相同的值会有问题. 接下来验证128
     */
    public class lockInteger03 {
        private static Integer lock01 = 1;
        private static Integer lock02 = 1;
        public static void main(String[] args) throws Exception {
    
            doRunByLock01("1-t1");
            doRunByLock01("1-t2");
            doRunByLock01("1-t3");
            doRunByLock01("1-t4");
            doRunByLock01("1-t5");
            doRunByLock01("1-t6");
            doRunByLock01("1-t7");
    
    
            doRunByLock02("2-t1");
            doRunByLock02("2-t2");
            doRunByLock02("2-t3");
            doRunByLock02("2-t4");
            doRunByLock02("2-t5");
            doRunByLock02("2-t6");
            doRunByLock02("2-t7");
        }
    
        private static void doRunByLock01(String name) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lock01) {
                        System.out.println("thread lock 01 : " + name + " start");
                        try {
                            System.out.println("thread lock 01 : " + name + " sleep. lock is :" + lock01);
                            TimeUnit.SECONDS.sleep(5L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("thread lock 01 : " + name + " end");
                    }
                }
            }).start();
        }
    
        private static void doRunByLock02(String name) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lock02) {
                        System.out.println("thread lock 02 : " + name + " start");
                        try {
                            System.out.println("thread lock 02 : " + name + " sleep. lock is :" + lock02);
                            TimeUnit.SECONDS.sleep(5L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("thread lock 02 : " + name + " end");
                    }
                }
            }).start();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    
    /**
     * 验证Integer值为128, 两个锁. 多个线程会不会并发执行
     * 结果: 会并发执行, Inter值如果大于 128 会并发执行.
     *  -128 <= lock <= 127 之间会顺序执行, 大于128会并发执行
     */
    public class lockInteger04 {
        private static Integer lock01 = -129;
        private static Integer lock02 = -129;
        public static void main(String[] args) throws Exception {
    
            doRunByLock01("1-t1");
            doRunByLock01("1-t2");
            doRunByLock01("1-t3");
            doRunByLock01("1-t4");
            doRunByLock01("1-t5");
            doRunByLock01("1-t6");
            doRunByLock01("1-t7");
    
    
            doRunByLock02("2-t1");
            doRunByLock02("2-t2");
            doRunByLock02("2-t3");
            doRunByLock02("2-t4");
            doRunByLock02("2-t5");
            doRunByLock02("2-t6");
            doRunByLock02("2-t7");
        }
    
        private static void doRunByLock01(String name) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lock01) {
                        System.out.println("thread lock 01 : " + name + " start");
                        try {
                            System.out.println("thread lock 01 : " + name + " sleep. lock is :" + lock01);
                            TimeUnit.SECONDS.sleep(5L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("thread lock 01 : " + name + " end");
                    }
                }
            }).start();
        }
    
        private static void doRunByLock02(String name) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (lock02) {
                        System.out.println("thread lock 02 : " + name + " start");
                        try {
                            System.out.println("thread lock 02 : " + name + " sleep. lock is :" + lock02);
                            TimeUnit.SECONDS.sleep(5L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("thread lock 02 : " + name + " end");
                    }
                }
            }).start();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
  • 相关阅读:
    设计模式2、抽象工厂模式 Abstract Factory
    计算机毕业设计Java酒店管理系统(源码+mysql数据库+系统+lw文档)
    Web中的相对路径和绝对路径、斜杠在Web中的不同意义
    综述 | 关于点云配准的全面综述(二)
    视口标签viewport
    java高级用法之:无所不能的java,本地方法调用实况
    MongoDB快速上手
    C++(21):特殊工具与技术
    【云原生】设备云之内外组织与管理
    字节跳动面试官:SpringBoot统一接口返回和全局异常处理怎么玩?
  • 原文地址:https://blog.csdn.net/zhanglong_4444/article/details/125386684