当前位置: 首页 > news >正文

JUC-多线程锁Synchronized锁的八种情况1

1、标准情况下: 

package com.nanjing.juc;

class Phone {

    public synchronized void sendSMS() throws Exception {
        System.out.println(Thread.currentThread().getName()+"---发短信---sendSMS");
    }

    public synchronized void sendEmail() throws Exception {
        System.out.println(Thread.currentThread().getName()+"---发邮件---sendEmail");
    }

}

public class ThreadDemo_10 {

    public static void main(String[] args) throws Exception {

        Phone phone = new Phone();

        new Thread(() -> {
            try {
                phone.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "AA").start();

        Thread.sleep(100);

        new Thread(() -> {
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}

  1. synchronized锁的对象是方法的调用者!

  2. 两个方法用的是同一个锁,谁先拿到谁执行!


2、sendSms方法延迟4秒

因为synchronized锁的对象是方法的调用者!

两个方法用的是同一个锁,谁先拿到谁执行!

AA线程先执行,拿到锁准备执行sendSms方法,

先等4秒,4秒后才开始打印AA---发短信---sendSMS

最后才执行sendEmail方法,打印BB---发邮件---sendEmail

package com.nanjing.juc;

import java.util.concurrent.TimeUnit;

class Phone1 {

    public synchronized void sendSMS() throws Exception {
        TimeUnit.SECONDS.sleep(4);//或者Thread.sleep(4000);
        System.out.println(Thread.currentThread().getName()+"---发短信---sendSMS");
    }

    public synchronized void sendEmail() throws Exception {
        //TimeUnit.SECONDS.sleep(4);//或者Thread.sleep(4000);
        System.out.println(Thread.currentThread().getName()+"---发邮件---sendEmail");
    }

}

public class ThreadDemo_11 {

    public static void main(String[] args) throws Exception {

        Phone1 phone1 = new Phone1();

        new Thread(() -> {
            try {
                phone1.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "AA").start();

        Thread.sleep(100);

        new Thread(() -> {
            try {
                phone1.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}


3、如果sendEmail方法延迟4秒,则结果不同

因为synchronized锁的对象是方法的调用者!

两个方法用的是同一个锁,谁先拿到谁执行!

AA线程先执行,拿到锁准备执行sendSms方法,打印AA---发短信---sendSMS

最后才执行sendEmail方法,先等4秒,4秒后打印BB---发邮件---sendEmail

package com.nanjing.juc;

import java.util.concurrent.TimeUnit;

class Phone1 {

    public synchronized void sendSMS() throws Exception {
        //TimeUnit.SECONDS.sleep(4);//或者Thread.sleep(4000);
        System.out.println(Thread.currentThread().getName()+"---发短信---sendSMS");
    }

    public synchronized void sendEmail() throws Exception {
        TimeUnit.SECONDS.sleep(4);//或者Thread.sleep(4000);
        System.out.println(Thread.currentThread().getName()+"---发邮件---sendEmail");
    }

}

public class ThreadDemo_11 {

    public static void main(String[] args) throws Exception {

        Phone1 phone1 = new Phone1();

        new Thread(() -> {
            try {
                phone1.sendSMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "AA").start();

        Thread.sleep(100);

        new Thread(() -> {
            try {
                phone1.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}

相关文章:

  • qt udp tcp代替RPC(一)
  • 刷题记录:牛客NC50965Largest Rectangle in a Histogram
  • 在线副业教程之 02 你学的越多,你赚的越多+你必须开始学习的5个最好的在线副业
  • VUE | key的内部原理、Vue监测数据的原理、Vue.set()和vm.$set()的使用
  • Centos/Docker 环境中文乱码如何解决
  • VS2019 Qt源码编译
  • Linux8-fork父子进程逻辑地址相同、进程的逻辑地址与物理地址、fork相关例题、僵死进程
  • java毕业设计普通中学体育卫生信息管理系统源码+lw文档+mybatis+系统+mysql数据库+调试
  • 基于C语言的查找算法汇编
  • 多网段多通道IP地址和通讯端口转换
  • 【PyQt】PyQt入门安装和Hello World
  • 怎样创建一个VUE项目(超简单)
  • C++【STL】【queue的使用和模拟实现】【priority_queue的使用和模拟实现】
  • SAP PI PO 接口常见问题处理:在监控器中找不到一个或多个 XI 消息的日志记录
  • L2TP客户端之Strongswan移植(三)
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • C学习-枚举(九)
  • Java|序列化异常StreamCorruptedException的解决方法
  • js 实现textarea输入字数提示
  • js对象的深浅拷贝
  • js中的正则表达式入门
  • k8s 面向应用开发者的基础命令
  • SpiderData 2019年2月23日 DApp数据排行榜
  • spring boot下thymeleaf全局静态变量配置
  • Travix是如何部署应用程序到Kubernetes上的
  • Vue2 SSR 的优化之旅
  • 创建一种深思熟虑的文化
  • 工作手记之html2canvas使用概述
  • 开源地图数据可视化库——mapnik
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 如何设计一个微型分布式架构?
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 树莓派 - 使用须知
  • 通过git安装npm私有模块
  • gunicorn工作原理
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • ​secrets --- 生成管理密码的安全随机数​
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (day 12)JavaScript学习笔记(数组3)
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (接口封装)
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .dwp和.webpart的区别
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .NET DataGridView数据绑定说明
  • .Net6 Api Swagger配置
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .net连接MySQL的方法