• 【JUC】Java并发编程从挖坑到入土全解(2)


    目录

    我们锁的到底是什么(8个案例)

    案例1

    案例2

    案例3

    案例4

    案例5

    案例6

    案例7

    案例8

    总结


    我们锁的到底是什么(8个案例)

    有a、b两个线程,我们基于如下代码进行改造:

    1. public static void main(String[] args) {
    2. Phone phoneA = new Phone();
    3. new Thread(() -> {
    4. phoneA.sendEmail();
    5. }, "a").start();
    6. try {
    7. TimeUnit.MICROSECONDS.sleep(200);
    8. } catch (InterruptedException e) {
    9. e.printStackTrace();
    10. }
    11. new Thread(() ->
    12. {
    13. phoneA.sendSMS();
    14. }, "b").start();
    15. }
    16. }
    17. class Phone {
    18. public synchronized void sendEmail() {
    19. System.out.println("sendEmail");
    20. }
    21. public synchronized void sendSMS() {
    22. System.out.println("sendSMS");
    23. }
    24. }

    请依次判断下在如下8个案例下,是先打印“sendEmail”?还是先打印“sendSMS”?

    案例1

    2个方法都是普通同步方法,方法内无其他逻辑(如下图)

    结果:先打印“sendEmail”,再打印“sendSMS”

    案例2

    打印“sendEmail”的方法中,添加暂停3秒的

    结果:(延迟3秒后)先打印“sendEmail”,再打印“sendSMS”

    案例3

    添加1个普通方法(无synchronized)

    结果:先打印“hello”,(延迟3秒后)再打印“sendEmail”

    案例4

    有2个phone(两个线程使用不同的phone对象)

    结果:先打印“sendSMS”,(延迟3秒后)再打印“sendEmail”

    案例5

    2个方法都是静态同步方法,只有一个phone(两个线程使用同一个phone对象)

    结果:(延迟3秒后)先打印“sendEmail”,再打印“sendSMS”

    案例6

    2个方法都是静态同步方法,有2个phone(两个线程使用不同的phone对象)

    结果:(延迟3秒后)先打印“sendEmail”,再打印“sendSMS”

    案例7

    1个方法是静态同步方法,1个方法是普通同步方法,有1个phone(两个线程使用同一个phone对象)

    结果:先打印“sendSMS”,(延迟3秒后)再打印“sendEmail”

    案例8

    1个方法是静态同步方法,1个方法是普通同步方法,有2个phone(两个线程使用不同的phone对象)

    结果:先打印“sendSMS”,(延迟3秒后)再打印“sendEmail”

    总结

    • 当对方法加synchronized关键字时,锁的是当前对象(this),所以即使是多线程只要调用的是同一个对象的synchronized方法,就需要串行执行(案例1和案例2),未被synchronized修饰的普通方法则不受影响(案例3)

    • 如果是不同对象则不受影响(案例4),分别在自己的对象上加锁,不会影响到别的对象

    • 当在带有“static”的方法上加了synchronized关键字时,锁的是当前类,无论几个对象,都要抢类的这一把锁,因而是否使用同一对象都会串行执行

    • 对于同步代码块呢,锁的是sychronized括号的对象

  • 相关阅读:
    springcloud学习笔记:使用hystrix实现服务熔断与服务降级
    一、Unity环境安装
    Linux进程概念(二)--进程状态&进程优先级
    Android音视频开发之GSYVideoPlayer
    【基于Netty实现Http通信、实现UDP单播和广播通信、代码案例实战学习】
    Java中@Data注解的作用
    腾讯云4核8G12M服务器支持多少人在线?
    [LeetCode/力扣][Java] 0946. 验证栈序列(Validate Stack Sequences)
    go开发之个微机器人的二次开发
    tcp rst 情况
  • 原文地址:https://blog.csdn.net/aqin1012/article/details/132948702