使用环境:多线程java程序中。

作用:在多线程的环境下,控制synchronized代码段不被多个线程同时执行。synchronized既可以加在一段代码上,也可以加在方法上。

使用:synchronized锁住的是括号里的对象,而不是代码。对于非static的synchronized方法,锁的就是对象本身也就是this。

通过以下两个案例说明:

  1. //包含了synchronized 方法的类
  2. public class SynchronizedMethod {
  3. public synchronized void test()
  4. {
  5. System.out.println("线程开始..");
  6. try {
  7. Thread.sleep(2000);
  8. } catch (Exception e) {
  9. e.printStackTrace();
  10. }
  11. System.out.println("线程结束..");
  12. }
  13. }
  14.  
  15. //测试类
  16. public class MyThread extends Thread{
  17. public void run(){
  18. SynchronizedMethod clazz = new SynchronizedMethod();
  19. clazz.test();
  20. }
  21.  
  22. public static void main(String[] args) {
  23. for(int i=0;i<3;i++)
  24. {
  25. Thread thread = new MyThread();
  26. thread.start();
  27. }
  28. }
  29.  
  30. }
  31.  
  32. 执行结果:

线程开始..
线程开始..
线程开始..
线程结束..
线程结束..
线程结束..

分析上述执行结果可知:

  当main方法执行时,分别创建了三个MyThread对象,而这三个对象又各自创建了独立的 SynchronizedMethred类,虽然使用了test方法使用了synchronized方法修饰,但是synchronized锁住的是三个独立的对象,因为三个对象各自分别执行了test方法。

因此,可以修改代码,让三个线程使用同一个SynchronizedMethod对象:

  1. //修改测试类代码如下,使用同一对象调用test方法
  2.  
  3. public class MyThread extends Thread{
  4.  
  5. /**
  6. * Author:LearnAndGet
  7. */
  8. private SynchronizedMethod sync;
  9. public MyThread(SynchronizedMethod sync)
  10. {
  11. this.sync = sync;
  12. }
  13.  
  14. public void run(){
  15. sync.test();
  16. }
  17.  
  18. public static void main(String[] args) {
  19. SynchronizedMethod sync = new SynchronizedMethod();
  20. for(int i=0;i<3;i++)
  21. {
  22. MyThread thread = new MyThread(sync);
  23. thread.start();
  24. }
  25. }
  26. }
  27.  
  28.  运行结果:

线程开始..
线程结束..
线程开始..
线程结束..
线程开始..
线程结束..

分析上述结果:由于每次新线程启动,使用的同一对象sync,因此synchronized生效了。

当然,更常用的方法是:使用schronized锁住这个类对应的Class对象:

  1. public class SynchronizedMethod {
  2. public void test()
  3. {
  4. //将代码块使用synchronized锁住
  5. synchronized(SynchronizedMethod.class)
  6. {
  7. System.out.println("线程开始..");
  8. try {
  9. Thread.sleep(2000);
  10. } catch (Exception e) {
  11. e.printStackTrace();
  12. }
  13. System.out.println("线程结束..");
  14. }
  15. }
  16. }

使用上述代码后,即使每次创建不同的SynchronizedMethod对象,执行其test方法时,因为synchronized锁住了SynchronizedMethod类对应的class对象,所以每次只能有一个SynchronizedMethod的对象获取锁,直到该锁获得释放,其他SynchronizedMethod对象都无法执行其方法。

上述代码中,通过使用 synchronized(SynchronizedMethod.class)实现了全局锁的效果

除此之外,使用 static synchronized一起修饰方法时,static方法可以直接类名加方法名调用,方法中无法使用this,所以它锁的不是this,而是类的Class对象,所以,static synchronized方法也相当于全局锁,相当于锁住了代码段。

Java synchronized到底锁住的是什么?的更多相关文章

  1. synchronized到底锁住的是谁?

    本文代码仓库:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/sync 先来一道校招级并发编程笔试题 题 ...

  2. java synchronized究竟锁住的是什么

    刚学java的时候,仅仅知道synchronized一个线程锁.能够锁住代码,可是它真的能像我想的那样,能够锁住代码吗? 在讨论之前先看一下项目中常见关于synchronized的使用方法: publ ...

  3. Java synchronized(this)锁住的是什么

    synchronized锁住的是括号里面的对象,而不是代码. 对于非static的synchronized方法,锁的就是对象本身,也就是this.

  4. Java同步方法:synchronized到底锁住了谁?

    目录 前言 同步方法 类的成员方法 类的静态方法 同步代码块 总结 其他同步方法 参考资料 前言 相信不少同学在上完Java课后,对于线程同步部分的实战,都会感到不知其然. 比如上课做实验的时候,按着 ...

  5. java synchronized类锁,对象锁详解(转载)

    觉得还不错 留个记录,转载自http://zhh9106.iteye.com/blog/2151791 在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看 ...

  6. 由Java 15废弃偏向锁,谈谈Java Synchronized 的锁机制

    Java 15 废弃偏向锁 JDK 15已经在2020年9月15日发布,详情见 JDK 15 官方计划.其中有一项更新是废弃偏向锁,官方的详细说明在:JEP 374: Disable and Depr ...

  7. JAVA synchronized关键字锁机制(中)

    synchronized 锁机制简单的用法,高效的执行效率使成为解决线程安全的首选. 下面总结其特性以及使用技巧,加深对其理解. 特性: 1. Java语言的关键字,当它用来修饰一个方法或者一个代码块 ...

  8. 关于synchronized无法锁住Integer原因

    原因 在多线程的时候,为了保证数据安全,必须在修改数据时使用线程同步,java中的synchronized用来实现线程同步.线程列队. 学完多线程基础的我,写一个多线程交替输出1,2,3,4,5... ...

  9. 关于Synchronized关键字锁住对象的嵌套问题

    如果在子关键字代码块中调用了sleep,是否会保留有所的锁?

随机推荐

  1. HashMap、HashTable、ConcurrentHashMap、TreeMap、LinkedHashMap、WeakHashMap区别

    1. HashMap   标准链地址法实现(下图).数组方式存储key/value,线程非安全,允许null作为key和value,key不可以重复,value允许重复,不保证元素迭代顺序是按照插入时 ...

  2. RabbitMQ入门教程(十五):普通集群和镜像集群

    原文:RabbitMQ入门教程(十五):普通集群和镜像集群 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.c ...

  3. ArcGis执行StartEditing(true)时,winform程序直接崩溃.

    问题描述:在Program中配置了ArcGis的许可,又在winform窗体添加了许可,导致执行StartEditing(true)时,winform程序直接崩溃. 原代码如下: static cla ...

  4. .net几种timer区别

    概述:.net框架不同名称控件都包含了各种timer,但每个timer有什么具体区别呢? 一.System.Threading private static void ThreadingTimer() ...

  5. js 学习一 猜数字游戏

    知识点 js 操作元素 增 (document.createElement(),document.body.appendChild()), 删(parentNode.removeChild()) ,改 ...

  6. 18Bootstrap

    1 概念 一个前端开发的框架,Bootstrap,来自 Twitter,是目前很受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JavaScript 的,它简洁灵活,使得 Web 开发 ...

  7. zencart批量表上传后 标题显示为网址 批量修改标题状态 SEO三要素

    zencart批量表上传后 标题显示为网址,原因是导入批量表时,产品标题对应状态被重置为0导致的 批量修改标题状态 ', metatags_products_name_status ', metata ...

  8. nginx的反向代理和配置

    最近有打算研读nginx源代码,看到网上介绍nginx可以作为一个反向代理服务器完成负载均衡.所以搜罗了一些关于反向代理服务器的内容,整理综合. 一  概述 反向代理(Reverse Proxy)方式 ...

  9. 公司内网机器vm ubuntu proxy 设置

    解决浏览器上网问题: System Setting -> Network -> Network Proxy设置公司的代理 解决apt联网问题: 在/etc/apt/apt.conf文件里加 ...

  10. jquery 中 html与text函数的区别

    jquery 中 html与text函数的区别 共同点:它们都能讲函数中的参数渲染到页面中: 异同点: text() 只是简单的讲参数的内容写入到页面中: html() 会根据参数的值,判断是否字体符 ...