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

synchronized 到底锁的是谁?

synchronized 到底锁的是谁?
修饰方法:
1、静态方法
2、非静态方法,锁住的是方法的调用者
修饰代码块

1、synchronized修饰非静态方法 锁住的是方法的调用者

锁住实例

流程:
1、线程A先拿到synModel对象然后给这个 synModel对象加上锁–接着等3s执行输出结束
2、线程B等1s后运行,此时 synModel对象 已经被 A拿到,所以他只能等待 等3s后,线程A释放 synModel对象,然后获取对象执行输出结束

public class SynchronizedTest {public static void main(String[] args) throws InterruptedException {SynModel synModel = new SynModel();new Thread(()->{synModel.fun1();},"A").start();TimeUnit.SECONDS.sleep(1);new Thread(()->{synModel.fun2();},"B").start();}
}
class SynModel{public synchronized void fun1()  {try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("1...");}public synchronized void fun2(){System.out.println("2...");}
}

情况1 不会排队

注意:下面这种情况是不会排队的,因为锁的是实例。

public class SynchronizedTest {public static void main(String[] args) throws InterruptedException {SynModel synModel1 = new SynModel();SynModel synModel2 = new SynModel();new Thread(()->{synModel1.fun1();},"A").start();TimeUnit.SECONDS.sleep(1);new Thread(()->{synModel2.fun2();},"B").start();}
}
class SynModel{public  synchronized void fun1()  {try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("1...");}public  synchronized void fun2(){System.out.println("2...");}
}

2 、修饰静态方法

只是把SynModel中的方法变成了静态的,注意此时锁住的是 SynModel这个类,不是锁的实例。会排队 先输出1后输出2

public class SynchronizedTest {public static void main(String[] args) throws InterruptedException {SynModel synModel1 = new SynModel();SynModel synModel2 = new SynModel();new Thread(()->{synModel1.fun1();},"A").start();TimeUnit.SECONDS.sleep(1);new Thread(()->{synModel2.fun2();},"B").start();}
}
class SynModel{public static synchronized void fun1()  {try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("1...");}public static synchronized void fun2(){System.out.println("2...");}
}

3、代码块

synchronized (this){}锁住的是SynModel这个对象。可以看到循环的五次都是同一个SynModel对象。所以五个线程 某个时刻只能有一个线程拿到这个SynModel对象 这个资源。
每个线程会依次输出start end


public class SynchronizedTest {public static void main(String[] args) {final SynModel synModel = new SynModel();for (int i = 0; i < 5; i++) {synModel.fun3();}}
}
class SynModel{public void fun3(){synchronized (this){System.out.println("start");try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("end");}}}

如果把对象放在循环里面,此时就是五个线程拿五个资源了。并没有去争夺资源

public class SynchronizedTest {public static void main(String[] args) {for (int i = 0; i < 5; i++) {final SynModel synModel = new SynModel();new Thread(()->{synModel.fun3();}).start();}}
}
class SynModel{public void fun3(){synchronized (this){System.out.println("ThreadName:"+Thread.currentThread().getName()+"start");try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("ThreadName:"+Thread.currentThread().getName()+"end");}}}

锁住SynModel.class 此时五个线程就会竞争,因为锁住的是 SynModel这个类,而不是实例对象了。

public class SynchronizedTest {public static void main(String[] args) {for (int i = 0; i < 5; i++) {final SynModel synModel = new SynModel();new Thread(()->{synModel.fun3();}).start();}}
}
class SynModel{public void fun3(){synchronized (SynModel.class){// this SynModel.classSystem.out.println("ThreadName:"+Thread.currentThread().getName()+"start");try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("ThreadName:"+Thread.currentThread().getName()+"end");}}}
http://www.lryc.cn/news/219011.html

相关文章:

  • 第六章:进制转换与数据存储
  • 【微服务】mysql + elasticsearch数据双写设计与实现
  • 《向量数据库指南》——用了解向量数据库Milvus Cloud搭建高效推荐系统
  • EtherCAT主站SOEM -- 4 -- SOEM之ethercatprint.h/c文件解析
  • Redis01-缓存击穿、穿透和雪崩
  • multiple kernel learning(MKL)多核学习
  • JS匿名函数之函数表达式与立即执行函数
  • WebGL:基础练习 / 简单学习 / demo / canvas3D
  • Python基础入门例程44-NP44 判断列表是否为空(条件语句)
  • 【每日一题Day369】LC187重复的DNA序列 | 字符串哈希
  • 服务器密码机主要功能及特点 安当加密
  • RIP路由配置
  • 尚硅谷Docker基础篇和Dockerfile超详细整合笔记
  • JavaScript_Date对象_实例方法_get类
  • Go语言在区块链开发中的应用
  • S4.2.4.5 Fast Training Sequence (FTS)
  • Gitlab CICD实用技巧汇总
  • JavaSpringbootMySQL高校实训管理平台01557-计算机毕业设计项目选题推荐(附源码)
  • 初阶JavaEE(14)表白墙程序
  • 算法设计与分析第二章作业
  • 《视觉SLAM十四讲》-- 三维空间的刚体运动
  • 关于iOS:如何使用SwiftUI调整图片大小?
  • 【MySQL】数据库MySQL基础知识与操作
  • vim手册(vim cheatsheet)
  • 软件测试具体人员分工
  • 计算机网络-应用层
  • linux 创建git项目并提交到gitee(保姆式教程)
  • STM32 IAP应用开发--bootloader升级程序
  • Q_GLOBAL_STATIC宏
  • [批处理]_[初级]_[如何删除变量值里的双引号]