• Java八锁现象



    八锁现象

    一、简介

    • synchronized 锁的对象是方法的调用者
    • 两个方法用的是同一个锁,谁先拿到谁执行
    • 普通的方法是用对象操作的(同步方法 对象)
    • static静态方法是用Class操作的(静态同步方法 Class)
    • new this 具体的一个手机
    • static Class 唯一的一个模板

    八种情况:
    两个同步方法,一个对象(发短信,打电话)
    两个同步方法,一个对象,发短信延迟(发短信,打电话)
    一个同步方法,一个普通方法,一个对象,同步方法延迟(打电话,发短信)
    两个同步方法,两个对象,发短信延迟(打电话,发短信)
    两个静态同步方法,一个对象,发短信延迟(发短信,打电话)
    两个静态同步方法,两个对象,发短信延迟(发短信,打电话)
    一个静态同步方法,一个普通同步方法,一个对象,静态同步方法延迟(打电话,发短信)
    一个普通同步方法,一个静态同步方法,两个对象,静态同步方法延迟(打电话,发短信)

    二、代码案例

    1、案例1

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:两个同步方法,一个对象(发短信,打电话)
     */
    public class Lock01 {
        public static void main(String[] args) {
    
            Phone phone = new Phone();
    
            // 锁的存在
            new Thread(() -> {
                phone.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone.call();
            }, "B").start();
        }
    }
    
    class Phone {
    
        // synchronized 锁的对象是方法的调用者
        // 两个方法用的是同一个锁,谁先拿到谁执行
        public synchronized void sendSms() {
            System.out.println("发短信");
        }
    
        public synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 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

    2、案例2

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:两个同步方法,一个对象,发短信延迟(发短信,打电话)
     */
    public class Lock02 {
        public static void main(String[] args) {
    
            Phone2 phone = new Phone2();
    
            // 锁的存在
            new Thread(() -> {
                phone.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone.call();
            }, "B").start();
        }
    }
    
    class Phone2 {
    
        // synchronized 锁的对象是方法的调用者
        // 两个方法用的是同一个锁,谁先拿到谁执行
        public synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        public synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 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

    3、案例3

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:一个同步方法,一个普通方法,一个对象,同步方法延迟(hello,发短信)
     */
    public class Lock03 {
        public static void main(String[] args) {
    
            Phone3 phone = new Phone3();
    
            new Thread(() -> {
                phone.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone.call();
            }, "B").start();
        }
    }
    
    class Phone3 {
    
        public synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        // 没有锁,不是同步方法,不受锁的影响
        public  void call() {
            System.out.println("打电话");
        }
    }
    
    • 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

    4、案例4

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:两个同步方法,两个对象,发短信延迟(打电话,发短信)
     */
    public class Lock04 {
        public static void main(String[] args) {
    
            // 两个对象,两个调用者,两把锁,与时间无关
            Phone4 phone1 = new Phone4();
            Phone4 phone2 = new Phone4();
    
            new Thread(() -> {
                phone1.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone2.call();
            }, "B").start();
        }
    }
    
    class Phone4 {
    
        // synchronized 锁的对象是方法的调用者
        // 两个方法用的是同一个锁,谁先拿到谁执行
        public synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        public synchronized void call() {
            System.out.println("打电话");
        }
    }	
    
    • 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

    5、案例5

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:两个静态同步方法,一个对象,发短信延迟(发短信,打电话)
     */
    public class Lock05 {
        public static void main(String[] args) {
    
            Phone5 phone = new Phone5();
    
            new Thread(() -> {
                phone.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone.call();
            }, "B").start();
        }
    }
    
    class Phone5 {
    
        // static 静态方法
        // 类一加载就有了,锁的是Class
        public static synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        public static synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 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

    6、案例6

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:两个静态同步方法,两个对象,发短信延迟(发短信,打电话)
     */
    public class Lock06 {
        public static void main(String[] args) {
    
            // 两个对象的Class类模板只有一个,static,锁的是Class类Phone6
            Phone6 phone1 = new Phone6();
            Phone6 phone2 = new Phone6();
    
            new Thread(() -> {
                phone1.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone2.call();
            }, "B").start();
        }
    }
    
    // Phone6 唯一的一个 Class 对象
    class Phone6 {
    
        // static 静态方法
        // 类一加载就有了,锁的是Class
        public static synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        public static synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 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

    7、案例7

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:一个静态同步方法,一个普通同步方法,一个对象,静态同步方法延迟(打电话,发短信)
     */
    public class Lock07 {
        public static void main(String[] args) {
    
            Phone7 phone = new Phone7();
    
            new Thread(() -> {
                phone.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone.call();
            }, "B").start();
        }
    }
    
    class Phone7 {
    
        //  静态同步方法,锁的是Class类模板
        public static synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        // 普通同步方法,锁的是调用者
        public synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 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

    8、案例8

    package com.sgz.lock8;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * 日期:2022/8/30 - 10:34
     * 需求:一个普通同步方法,一个静态同步方法,两个对象,静态同步方法延迟(打电话,发短信)
     */
    public class Lock08 {
        public static void main(String[] args) {
    
            // 两个对象的Class类模板只有一个,static,锁的是Class类Phone6
            Phone8 phone1 = new Phone8();
            Phone8 phone2 = new Phone8();
    
            new Thread(() -> {
                phone1.sendSms();
            }, "A").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> {
                phone2.call();
            }, "B").start();
        }
    }
    
    class Phone8 {
    
        // static 静态方法
        // 类一加载就有了,锁的是Class
        public static synchronized void sendSms() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发短信");
        }
    
        public synchronized void call() {
            System.out.println("打电话");
        }
    }
    
    • 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
  • 相关阅读:
    区块链技术的应用场景和优势
    python中的继承
    分布式调度器xxl-job
    day47:C++ day7,异常处理、using的第三种用法、类型转换、lambda表达式、STL标准模板库
    卷积神经网络模型之——LeNet网络结构与代码实现
    Cortex-R52 深度分析总目录
    pip install torch
    Oracle12c新特性大全 存储资源隔离+flex+diskgroup
    VirtualBox 安装UOS统信服务器操作系统
    Vue 使用vue-cli构建SPA项目(超详细)
  • 原文地址:https://blog.csdn.net/s17856147699/article/details/126598600