1、new this 调用的是这个对象,是一个具体的对象!
2、static class 唯一的一个模板!

场景一

  1. package com.yuanzi.lock8;
  2. import java.util.concurrent.TimeUnit;
  3. /**
  4. * @program: practice
  5. * @description: 8锁, 就是关于锁的8个问题
  6. * 问题1. 标准情况下, 两个线程是先打印 发短信还是打电话.
  7. * @author: yuanzi
  8. * @create: 2021-06-05 12:28
  9. **/
  10. public class Test1 {
  11. public static void main(String[] args) throws InterruptedException {
  12. //问题1. 标准情况下, 两个线程是先打印 发短信还是打电话.
  13. //发短信,锁的对象是同一个,先谁拿到就谁先执行
  14. Phone1 phone1 = new Phone1();
  15. new Thread(() -> phone1.sendSms(),"A").start();
  16. TimeUnit.SECONDS.sleep(1);
  17. new Thread(() -> phone1.call(),"B").start();
  18. }
  19. }
  20. class Phone1{
  21. //synchronized 锁的对象是方法的调用者
  22. //2个方法用的是同一个锁, 谁先拿个谁先执行
  23. public synchronized void sendSms(){
  24. System.out.println("sendSms");
  25. }
  26. public synchronized void call(){
  27. System.out.println("call");
  28. }
  29. }

场景二

  1. package com.yuanzi.lock8;
  2. import java.util.concurrent.TimeUnit;
  3. /**
  4. * @program: practice
  5. * @description:
  6. * 问题2, 方法1添加4秒等待, 那打印顺序呢? 先sendSms还是先call.
  7. * @author: yuanzi
  8. * @create: 2021-06-05 13:23
  9. **/
  10. public class Test2 {
  11. public static void main(String[] args) throws InterruptedException {
  12. //问题2, 方法1添加4秒等待, 那打印顺序呢? 先sendSms还是先call.
  13. //发短信,谁先拿锁到谁先执行
  14. Phone2 phone2 = new Phone2();
  15. new Thread(() -> phone2.sendSms(),"A").start();
  16. TimeUnit.SECONDS.sleep(1);
  17. new Thread(() -> phone2.call(),"B").start();
  18. }
  19. }
  20. class Phone2{
  21. //synchronized 锁的对象是方法的调用者
  22. //2个方法用的是同一个锁, 谁先拿个谁先执行
  23. public synchronized void sendSms(){
  24. //问题2, 方法1添加4秒等待, 那打印顺序呢? 先sendSms还是先call
  25. try{
  26. TimeUnit.SECONDS.sleep(4);
  27. }catch (InterruptedException e){
  28. e.printStackTrace();
  29. }
  30. System.out.println("sendSms");
  31. }
  32. public synchronized void call(){
  33. System.out.println("call");
  34. }
  35. }

场景三

  1. package com.yuanzi.lock8;
  2. import java.util.concurrent.TimeUnit;
  3. /**
  4. * @program: practice
  5. * @description:
  6. * 问题3, 增加一个普通方法后! 先执行发短信还是Hello?
  7. * @author: yuanzi
  8. * @create: 2021-06-05 13:29
  9. **/
  10. public class Test3 {
  11. public static void main(String[] args) throws InterruptedException {
  12. //问题3, 增加一个普通方法后! 先执行发短信还是打电话?
  13. //打电话, 普通方法不受同步的影响
  14. Phone3 phone3 = new Phone3();
  15. new Thread(() -> phone3.sendSms(),"A").start();
  16. TimeUnit.SECONDS.sleep(1);
  17. new Thread(() -> phone3.call(),"B").start();
  18. }
  19. }
  20. class Phone3 {
  21. //synchronized 锁的对象是方法的调用者
  22. //2个方法用的是同一个锁, 谁先拿个谁先执行
  23. public synchronized void sendSms() {
  24. try {
  25. TimeUnit.SECONDS.sleep(4);
  26. } catch (InterruptedException e) {
  27. e.printStackTrace();
  28. }
  29. System.out.println("sendSms");
  30. }
  31. //这里没有锁! 不是同步方法, 不受锁的影响
  32. public void call() {
  33. System.out.println("call");
  34. }
  35. }

场景四

  1. package com.yuanzi.lock8;
  2. import java.util.concurrent.TimeUnit;
  3. /**
  4. * @program: practice
  5. * @description:
  6. * 问题4, 两个对象,两个同步方法, 是先发短信还是先打电话?
  7. * @author: yuanzi
  8. * @create: 2021-06-05 13:39
  9. **/
  10. public class Test4 {
  11. public static void main(String[] args) throws InterruptedException {
  12. //问题4, 两个对象,两个同步方法, 是先发短信还是先打电话? 打电话, 竞争的不是同一把锁.
  13. //打电话, 竞争的不是同一把锁. 两个对象, 2个调用者, 2把锁
  14. Phone4 phone1 = new Phone4();
  15. Phone4 phone2 = new Phone4();
  16. new Thread(() -> phone1.sendSms(),"A").start();
  17. TimeUnit.SECONDS.sleep(1);
  18. new Thread(() -> phone2.call(),"B").start();
  19. }
  20. }
  21. class Phone4{
  22. //synchronized 锁的对象是方法的调用者
  23. //2个方法用的是同一个锁, 谁先拿个谁先执行
  24. public synchronized void sendSms(){
  25. try{
  26. TimeUnit.SECONDS.sleep(4);
  27. }catch (InterruptedException e){
  28. e.printStackTrace();
  29. }
  30. System.out.println("sendSms");
  31. }
  32. public synchronized void call(){
  33. System.out.println("call");
  34. }
  35. }

场景五

package com.yuanzi.lock8;

import java.util.concurrent.TimeUnit;

/**
 * @program: practice
 * @description:
 * 问题5, 增加2个静态的同步方法, 只有一个对象, 先打印还是先打电话,  先打印.  锁的是同一个class
 * @author: yuanzi
 * @create: 2021-06-05 13:39
 **/
public class Test5 {
    public static void main(String[] args) throws InterruptedException {
        //问题5, 增加2个静态的同步方法, 只有一个对象, 先打印发短信还是先打电话?
        //发短信. 前面锁的是对象, 这里锁的是class而且是同一个class类模板
        new Thread(()  -> Phone5.sendSms(),"A").start();
        TimeUnit.SECONDS.sleep(1);
        new Thread(()  -> Phone5.call(),"B").start();
    }
}

class Phone5{
    //synchronized static 静态方法,类加载就存在, 锁的是class
    public static synchronized void sendSms(){
        try{
            TimeUnit.SECONDS.sleep(4);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("sendSms");
    }

    public static synchronized void call(){
        System.out.println("call");
    }
}

场景六

package com.yuanzi.lock8;

import java.util.concurrent.TimeUnit;

/**
 * @program: practice
 * @description:
 * 问题6, 两个对象! 增加2个静态的同步方法, 先打印 发短信还是打电话?
 * @author: yuanzi
 * @create: 2021-06-05 13:40
 **/
public class Test6 {
    public static void main(String[] args) throws InterruptedException {
        // 问题6, 两个对象! 增加2个静态的同步方法, 先打印 发短信还是打电话?
        // 发短信,两个对象的class类模板只有一个,static,锁的是class
        Phone6 phone6_1 = new Phone6();
        Phone6 phone6_2 = new Phone6();
        new Thread(()  -> phone6_1.sendSms(),"A").start();
        TimeUnit.SECONDS.sleep(1);
        new Thread(()  -> phone6_2.call(),"B").start();
    }
}

class Phone6{
    //synchronized static 静态方法,类加载就存在, 锁的是class
    public static synchronized void sendSms(){
        try{
            TimeUnit.SECONDS.sleep(4);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("sendSms");
    }

    public static synchronized void call(){
        System.out.println("call");
    }
}

场景七

package com.yuanzi.lock8;

import java.util.concurrent.TimeUnit;

/**
 * @program: practice
 * @description:
 * @author: yuanzi
 * @create: 2021-06-05 13:40
 **/
public class Test7 {
    public static void main(String[] args) throws InterruptedException {
        //问题7, 1个静态方法,1个普通同步方法, 只有一个对象, 先打印发短信还是先打电话?
        //发打电话. 2把锁,普通同步方法调用的是对象锁
        Phone7 phone7 = new Phone7();
        new Thread(()  -> phone7.sendSms(),"A").start();
        TimeUnit.SECONDS.sleep(1);
        new Thread(()  -> phone7.call(),"B").start();
    }
}

class Phone7{
    //静态的同步方法, 锁的是class类模板
    public static synchronized void sendSms(){
        try{
            TimeUnit.SECONDS.sleep(4);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("sendSms");
    }
    //普通的同步方法, 锁的是调用的对象
    public synchronized void call(){
        System.out.println("call");
    }
}

场景八

package com.yuanzi.lock8;

import java.util.concurrent.TimeUnit;

/**
 * @program: practice
 * @description:
 * 问题8, 1个静态方法,1个普通同步方法, 2个对象, 先打印发短信还是先打电话?
 * @author: yuanzi
 * @create: 2021-06-05 13:40
 **/
public class Test8 {
    public static void main(String[] args) throws InterruptedException {
        //问题8, 1个静态方法,1个普通同步方法, 2个对象, 先打印发短信还是先打电话?
        //发打电话. 这里有3把锁,不同对象是不同的对象锁, 静态的是同一把锁
        Phone8 phone8_1 = new Phone8();
        Phone8 phone8_2 = new Phone8();
        new Thread(()  -> phone8_1.sendSms(),"A").start();
        TimeUnit.SECONDS.sleep(1);
        new Thread(()  -> phone8_2.call(),"B").start();
    }
}

class Phone8{
    //静态的同步方法, 锁的是class类模板
    public static synchronized void sendSms(){
        try{
            TimeUnit.SECONDS.sleep(4);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("sendSms");
    }
    //普通的同步方法, 锁的是调用的对象
    public synchronized void call(){
        System.out.println("call");
    }
}