JUC -多线程锁问题:

懵懂的女人 提交于 2020-03-09 06:25:24

多线程锁问题:

在这里插入图片描述

  1. 8锁现象下名词解释:

    • 顺序执行:先调用的先执行

    • 随机执行:没有规律,与计算机硬件资源有关,哪个线程先得到资源就先执行,各个线程之间互不干扰。

  2. 多个线程使用同一把锁-顺序执行 多个线程使用同一个对象,多个线程就是使用一把锁,先调用的先执行!

    public class MultiThreadUseOneLock01 {
        public static void main(String[] args){
    
            Mobile mobile = new Mobile();
            // 两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行!
            new Thread(()->mobile.sendEmail(),"A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(()->mobile.sendMS(),"B").start();
        }
    }
    
    // 手机,发短信,发邮件
    class Mobile {
        // 被 synchronized 修饰的方法、锁的对象是方法的调用者、
        public synchronized void sendEmail() {
            System.out.println("sendEmail");
        }
    
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    }
    
  3. 多个线程使用同一把锁,其中某个线程里面还有阻塞-顺序执行****多个线程使用同一个对象,多个线程就是使用一把锁,先调用的先执行,即使在某方法中设置了阻塞

    public class MultiThreadUseOneLock02 {
        public static void main(String[] args){
    
            Mobile2 mobile = new Mobile2();
            // 两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行!
            new Thread(()->mobile.sendEmail(),"A").start();
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(()->mobile.sendMS(),"B").start();
        }
    }
    
    // 手机,发短信,发邮件
    class Mobile2 {
        // 被 synchronized 修饰的方法、锁的对象是方法的调用者、
        public synchronized void sendEmail() {
    
            //多个线程使用一把锁,这里设置一个干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    }
    
    
  4. 多个线程有锁与没锁-随机执行 多个线程,有的线程有锁,有的线程没锁,两者之间不存在竞争同一把锁的情况,先后执行顺序是随机的。

    
    public class MultiThreadHaveLockAndNot03 {
        public static void main(String[] args){
    
            Mobile3 mobile = new Mobile3();
            // 两个线程使用的是同一个对象。两个线程是一把锁!先调用的先执行!
            new Thread(()->mobile.sendEmail(),"A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(()->mobile.sendMS(),"B").start();
    
            new Thread(()->mobile.getWeixinMs(),"C").start();
        }
    }
    
    // 手机,发短信,发邮件
    class Mobile3 {
        // 被 synchronized 修饰的方法、锁的对象是方法的调用者、
        public synchronized void sendEmail() {
    
            //多个线程使用一把锁,这里设置一个干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    
        //接收微信,没有锁
        public void getWeixinMs() {
            System.out.println("getWeixinMs");
        }
    }
    
    
  5. 多个线程使用多把锁-随机执行 被 synchronized 修饰的方法,锁的对象是方法的调用者;调用者不同,它们之间用的不是同一个锁,相互之间没有关系

    
    public class MultiThreadUseMultiLock04 {
        public static void main(String[] args){
    
            // 两个对象,互不干预
            Mobile4 mobile1 = new Mobile4();
            Mobile4 mobile2 = new Mobile4();
    
            new Thread(()->mobile1.sendEmail(),"A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(()->mobile2.sendMS(),"B").start();
        }
    }
    
    // 手机,发短信,发邮件
    class Mobile4 {
        /**
         *  @description:
         *  被 synchronized 修饰的方法,锁的对象是方法的调用者;
         *  调用者不同,它们之间用的不是同一个锁,相互之间没有关系。
         */
        public synchronized void sendEmail() {
    
            //这里设置一个干扰
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    }
    
  6. Class锁:多个线程使用一个对象-顺序执行 被 synchronized 和 static 同时修饰的方法,锁的对象是类的 class 对象,是唯一的一把锁。线程之间是顺序执行

    
    public class MultiThreadUseOneObjectOneClassLock05 {
        public static void main(String[] args){
    
    
            Mobile5 mobile = new Mobile5();
    
            new Thread(()->mobile.sendEmail(),"A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(()->mobile.sendMS(),"B").start();
        }
    }
    
    // 手机,发短信,发邮件
    class Mobile5 {
    
    
    
        public synchronized static void sendEmail() {
    
            //这里设置一个干扰
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        public synchronized static void sendMS() {
            System.out.println("sendMS");
        }
    }
    
    
  7. Class锁:多个线程使用多个对象-顺序执行被 synchronized 修饰 和 static 修饰的方法,锁的对象是类的 class 对象,是唯一的一把锁。Class锁是唯一的,所以多个对象使用的也是同一个Class锁

    
    public class MultiThreadUseMultiObjectOneClassLock06 {
        public static void main(String[] args){
    
    
            Mobile6 mobile1 = new Mobile6();
            Mobile6 mobile2 = new Mobile6();
    
            new Thread(()->mobile1.sendEmail(),"A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(()->mobile2.sendMS(),"B").start();
        }
    }
    
    // 手机,发短信,发邮件
    class Mobile6 {
        public synchronized static void sendEmail() {
    
            //这里设置一个干扰
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        public synchronized static void sendMS() {
            System.out.println("sendMS");
        }
    }
    
  8. Class锁与对象锁:多个线程使用一个对象-随机执行被 synchronized和static修饰的方法,锁的对象是类的class对象!唯一的同一把锁;只被synchronized修饰的方法,是普通锁(如对象锁),不是Class锁,所以进程之间执行顺序互不干扰

    public class MultiThreadUseOneObjectClassLockAndObjectLock07 {
        public static void main(String[] args){
    
    
            Mobile7 mobile = new Mobile7();
    
            new Thread(()->mobile.sendEmail(),"A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(()->mobile.sendMS(),"B").start();
        }
    }
    
    // 手机,发短信,发邮件
    class Mobile7 {
     
        public synchronized static void sendEmail() {
    
            //这里设置一个干扰
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        /**
         *  @description:
         *  普通同步锁:对象锁
         */
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    }
    
    
  9. Class锁与对象锁:多个线程使用多个对象-随机执行被 synchronized和static修饰的方法,锁的对象是类的class对象!唯一的同一把锁;只被synchronized修饰的方法,是普通锁(如对象锁),不是Class锁,所以进程之间执行顺序互不干扰

    public class MultiThreadUseMultiObjectClassLockAndObjectLock08 {
        public static void main(String[] args){
    
            Mobile8 mobile1 = new Mobile8();
            Mobile8 mobile2 = new Mobile8();
            new Thread(()->mobile1.sendEmail(),"A").start();
    
            // 干扰
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(()->mobile2.sendMS(),"B").start();
        }
    }
    
    // 手机,发短信,发邮件
    class Mobile8 {
       
        public synchronized static void sendEmail() {
    
            //这里设置一个干扰
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendEmail");
        }
    
        /**
         *  @description:
         *  普通同步锁:对象锁
         */
        public synchronized void sendMS() {
            System.out.println("sendMS");
        }
    }
    
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!