• 线程基础知识05 synchronized类锁和对象锁演示


    1 简介

      synchronized在方法内,同步代码块,传入对象,使用的是对象锁,传入class对象,使用的是类锁

      作用于普通方法,也是对象锁,当前对象

      作用于静态方法,是类锁

    2 同步方法示例

    2.1

    两个synchronized 修饰的普通方法

    public class SychTest1 {
    
        static class Phone{
            synchronized void  sendEmail(){
                System.out.println("EMAIL");
            }
            synchronized void sendMsg(){
                System.out.println("MSG");
            }
        }
    
        public static void main(String[] args) {
    
            Phone p = new Phone();
    
            new Thread(()->{
                p.sendEmail();
            }).start();
    
            try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
    
            new Thread(()->{
                p.sendMsg();
            }).start();
        }
    }

    执行结果,持有同一个锁对象p

    EMAIL
    MSG

    2.2

    两个synchronized 修饰的普通方法,sendEmail睡了2秒

    public class SychTest2 {
    
        static class Phone{
            synchronized void sendEmail(){
                try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
                System.out.println("EMAIL");
            }
            synchronized void sendMsg(){
                System.out.println("MSG");
            }
        }
    
        public static void main(String[] args) {
    
            Phone p = new Phone();
    
            new Thread(()->{
                p.sendEmail();
            }).start();
            
            try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
            new Thread(()->{
                p.sendMsg();
            }).start();
        }
    }

    执行结果,持有同一个锁对象p,所以还是sendEmail先执行

    EMAIL
    MSG

    2.3

    一个同步方法,一个普通方法

    public class SychTest3 {
    
        static class Phone{
            synchronized void sendEmail(){
                try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
                System.out.println("EMAIL");
            }
            void sendMsg(){
                System.out.println("MSG");
            }
    
        }
    
        public static void main(String[] args) {
    
            Phone p = new Phone();
    
            new Thread(()->{
                p.sendEmail();
            }).start();
    
    
            try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
    
            new Thread(()->{
                p.sendMsg();
            }).start();
        }
        
    }

    执行结果

    MSG
    EMAIL

    2.4

    两个同步方法,但是是两个不同的对象p和p2去调用同步方法

    public class SychTest4 {
    
        static class Phone{
            synchronized void sendEmail(){
                try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
                System.out.println("EMAIL");
            }
            synchronized void sendMsg(){
                System.out.println("MSG");
            }
            
        }
    
        public static void main(String[] args) {
    
            Phone p = new Phone();
    
            Phone p2 = new Phone();
    
            new Thread(()->{
                p.sendEmail();
            }).start();
    
    
            try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
    
            new Thread(()->{
                p2.sendMsg();
            }).start();
        }
    }

    执行结果,持有的是不同的锁对象p和p2

    MSG
    EMAIL

    2.5

    两个静态同步方法

    public class SychTest5 {
    
        static class Phone{
            synchronized static void sendEmail(){
                try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
                System.out.println("EMAIL");
            }
            synchronized static void sendMsg(){
                System.out.println("MSG");
            }
        }
    
        public static void main(String[] args) {
    
            Phone p = new Phone();
    
            new Thread(()->{
                p.sendEmail();
            }).start();
    
    
            try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
    
            new Thread(()->{
                p.sendMsg();
            }).start();
        }
    }

    执行结果,持有的是同一个类锁

    EMAIL
    MSG

    2.6

    两个静态同步方法,两个对象p和p2去调用

    public class SychTest6 {//?
    
        static class Phone{
            synchronized static void sendEmail(){
                try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
                System.out.println("EMAIL");
            }
            synchronized static void sendMsg(){
                System.out.println("MSG");
            }
        }
    
        public static void main(String[] args) {
    
            Phone p = new Phone();
            Phone p2 = new Phone();
    
            new Thread(()->{
                p.sendEmail();
            }).start();
    
    
            try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
    
            new Thread(()->{
                p2.sendMsg();
            }).start();
        }
    }

    执行结果,持有的是同一个类锁,和哪个对象去调用无关

    EMAIL
    MSG

    2.7

    一个静态同步,一个非静态同步

    public class SychTest7 {
    
        static class Phone{
            synchronized static void sendEmail(){
                try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
                System.out.println("EMAIL");
            }
            synchronized  void sendMsg(){
                System.out.println("MSG");
            }
        }
    
        public static void main(String[] args) {
    
            Phone p = new Phone();
    
            new Thread(()->{
                p.sendEmail();
            }).start();
    
    
            try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
    
            new Thread(()->{
                p.sendMsg();
            }).start();
        }
    
    }

    执行结果,一个持有类锁,一个持有对象锁

    MSG
    EMAIL

    2.8

    一个静态同步方法,一个非静态同步方法,两个对象去调用

    public class SychTest8 {
    
        static class Phone{
            synchronized static void sendEmail(){
                try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }
                System.out.println("EMAIL");
            }
            synchronized  void sendMsg(){
                System.out.println("MSG");
            }
        }
    
        public static void main(String[] args) {
    
            Phone p = new Phone();
    
            Phone p2 = new Phone();
    
    
            new Thread(()->{
                p.sendEmail();
            }).start();
    
    
            try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
    
            new Thread(()->{
                p2.sendMsg();
            }).start();
        }
    }

    执行结果,一个持有类锁,一个持有对象锁

    MSG
    EMAIL

    3 同步代码示例

    3.1

    传入class对象

    public class SychTest13 {
    
        public static synchronized  void aa()  {
            System.out.println("aaa");
        }
    
        public static void main(String[] args) throws InterruptedException {
    
            new Thread(()->{
                synchronized (SychTest13.class){
                    try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
                    System.out.println("aaaaaaaaaaaa");
                }
            }).start();
    
            new Thread(()->{
                synchronized (SychTest13.class){
                    System.out.println("bbbbbbbbbb");
                }
            }).start();
        }
    }

    执行结果

    aaaaaaaaaaaa
    bbbbbbbbbbb

    3.2

    传入同一个对象t1

    public class SychTest14 {
    
        public static synchronized  void aa()  {
            System.out.println("aaa");
        }
    
        public static void main(String[] args) throws InterruptedException {
            SychTest13 t1 = new SychTest13();
            new Thread(()->{
                synchronized (t1){
                    try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
                    System.out.println("aaaaaaaaaaaa");
                }
            }).start();
    
            new Thread(()->{
                synchronized (t1){
                    System.out.println("bbbbbbbbbb");
                }
            }).start();
        }
    }

    执行结果

    aaaaaaaaaaaa
    bbbbbbbbbbb

    3.3

    传入对象t1和t2

    public class SychTest15 {
    
        public static synchronized  void aa()  {
            System.out.println("aaa");
        }
    
        public static void main(String[] args) throws InterruptedException {
            SychTest13 t1 = new SychTest13();
            SychTest13 t2 = new SychTest13();
            new Thread(()->{
                synchronized (t1){
                    try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
                    System.out.println("aaaaaaaaaaaa");
                }
            }).start();
    
            new Thread(()->{
                synchronized (t2){
                    System.out.println("bbbbbbbbbb");
                }
            }).start();
        }
    }

    执行结果

    bbbbbbbbbb
    aaaaaaaaaaaa
  • 相关阅读:
    独家全新2019超级签名源码/超级签/ios分发/签名端本地linux服务器完成签名带部署文档
    YYC松鼠短视频系统加入openinstall插件SDK实现免邀请码注册统计和安装统计-详细方法
    程序员男朋友没空搭理人吗?现实中程序员真的忙到女朋友都不要搭理了吗?
    献给攻击者,请放弃攻击吧,这样只会浪费自己的青春+金钱
    新奇怪知识:用ps导出gif图片放在网页上可实现只循环一次并且定格不变,本地一直循环
    uniapp配置去掉友盟无法打包,提示配置错误如何解决
    git切换分支报错error: Your local changes to the following files would be overwritten by checkout:
    数字信号处理--卷积的意义
    傅立叶分析和小波分析之间的关系?
    傅里叶变换:MP3、JPEG和Siri背后的数学
  • 原文地址:https://www.cnblogs.com/jthr/p/16050641.html
Copyright © 2020-2023  润新知