Java 同步锁(synchronized)详解及实例

发布时间 - 2026-01-11 00:24:46    点击率:

Java 同步锁(synchronized)详解及实例

Java中cpu分给每个线程的时间片是随机的并且在Java中好多都是多个线程共用一个资源,比如火车卖票,火车票是一定的,但卖火车票的窗口到处都有,每个窗口就相当于一个线程,这么多的线程共用所有的火车票这个资源。如果在一个时间点上,两个线程同时使用这个资源,那他们取出的火车票是一样的(座位号一样),这样就会给乘客造成麻烦。比如下面程序:

package com.pakage.ThreadAndRunnable; 
 
public class Runnable_demo implements Runnable{ 
  private int ticket=10; 
  public Runnable_demo(){    
  } 
  @Override 
  public void run() { 
    for(int i=0;i<20;i++){ 
        if(this.ticket>0){ 
          //休眠1s秒中,为了使效果更明显,否则可能出不了效果 
          try { 
            Thread.sleep(1000); 
          } catch (Exception e) { 
            e.printStackTrace(); 
          } 
          System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); 
        } 
       
    } 
  } 
   
   public static void main(String args[]){ 
     Runnable_demo demo=new Runnable_demo(); 
     //基于火车票创建三个窗口 
     new Thread(demo,"a").start(); 
     new Thread(demo,"b").start(); 
     new Thread(demo,"c").start(); 
   } 
   
} 

程序运行结果:


我们可以看到c号窗口和和b号窗口都卖出了10号票,并且a号和b号窗口分别卖出了0号和-1号票。造成这种情况的原因是1、c线程和b线程在ticket=10的时候,c线程取出10号票以后,ticket还没来的及减1,b线程就取出了ticket此时ticket还等于10;2、在ticket=1时,c线程取出了1号票,ticket还没来的及减1,a、b线程就先后进入了if判断语句,这时ticket减1了,那么当a、b线程取票的时候就取到了0号和-1号票。

出现了上述情况怎样改变呢,我们可以这样做:当一个线程要使用火车票这个资源时,我们就交给它一把锁,等它把事情做完后在把锁给另一个要用这个资源的线程。这样就不会出现上述情况。 实现这个锁的功能就需要用到synchronized这个关键字。

synchronized这个关键字有两种用法1、放方法名前形成同步方法;2、放在块前构成同步块。

1、使用同步方法将上面的例子该为:

package com.pakage.ThreadAndRunnable; 
 
public class Runnable_demo implements Runnable{ 
  private int ticket=10; 
  public Runnable_demo(){    
  } 
  @Override 
  public void run() { 
    for(int i=0;i<20;i++){ 
        if(this.ticket>0){ 
          //休眠1s秒中,为了使效果更明显,否则可能出不了效果 
          try { 
            Thread.sleep(1000); 
          } catch (Exception e) { 
            e.printStackTrace(); 
          } 
          this.sale(); 
        } 
       
    } 
  } 
   
  public synchronized void sale(){ 
    if(this.ticket>0){ 
      System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); 
    } 
  } 
   
   public static void main(String args[]){ 
     Runnable_demo demo=new Runnable_demo(); 
     //基于火车票创建三个窗口 
     new Thread(demo,"a").start(); 
     new Thread(demo,"b").start(); 
     new Thread(demo,"c").start(); 
   } 
   
} 

程序的输出结果为:

2、使用同步块修改上面的例子:

package com.pakage.ThreadAndRunnable; 
 
public class Runnable_demo implements Runnable{ 
  private int ticket=10; 
  public Runnable_demo(){    
  } 
  @Override 
  public void run() { 
    for(int i=0;i<20;i++){ 
      <span style="color:#ff0000">synchronized</span>(this){ 
        if(this.ticket>0){ 
          //休眠1s秒中,为了使效果更明显,否则可能出不了效果 
          try { 
            Thread.sleep(1000); 
          } catch (Exception e) { 
            e.printStackTrace(); 
          } 
          System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); 
        } 
      } 
       
    } 
  } 
   
   public static void main(String args[]){ 
     Runnable_demo demo=new Runnable_demo(); 
     //基于火车票创建三个窗口 
     new Thread(demo,"a").start(); 
     new Thread(demo,"b").start(); 
     new Thread(demo,"c").start(); 
   } 
   
} 

程序的输出结果:

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# Java  # 同步锁  # synchronized  # 同步锁详解  # Java中的synchronized有几种加锁方式(实例详解)  # java synchronized 锁机制原理详解  # 解析Java编程之Synchronized锁住的对象  # Java同步锁synchronized用法的最全总结  # java中synchronized锁的升级过程  # Java Synchronized锁失败案例及解决方案  # Java synchronized的锁升级过程详解  # 一文详细讲解Java中有哪些锁  # 出了  # 没来  # 都是  # 卖出了  # 都有  # 放在  # 多个  # 这么多  # 我们可以  # 希望能  # 这样做  # 要用  # 可以看到  # 这种情况  # 会给  # 有两种  # 谢谢大家  # 完后  # 给它  # 要使 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 想要更高端的建设网站,这些原则一定要坚持!  Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】  Python结构化数据采集_字段抽取解析【教程】  晋江文学城电脑版官网 晋江文学城网页版直接进入  ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】  公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?  微信小程序 五星评分(包括半颗星评分)实例代码  如何在 Pandas 中基于一列条件计算另一列的分组均值  Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】  详解CentOS6.5 安装 MySQL5.1.71的方法  如何用y主机助手快速搭建网站?  微信推文制作网站有哪些,怎么做微信推文,急?  Java类加载基本过程详细介绍  如何在IIS中新建站点并配置端口与物理路径?  Laravel怎么使用artisan命令缓存配置和视图  如何在橙子建站中快速调整背景颜色?  ChatGPT 4.0官网入口地址 ChatGPT在线体验官网  用v-html解决Vue.js渲染中html标签不被解析的问题  Firefox Developer Edition开发者版本入口  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  浅谈javascript alert和confirm的美化  bing浏览器学术搜索入口_bing学术文献检索地址  如何快速使用云服务器搭建个人网站?  什么是javascript作用域_全局和局部作用域有什么区别?  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  大连 网站制作,大连天途有线官网?  如何快速建站并高效导出源代码?  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  php在windows下怎么调试_phpwindows环境调试操作说明【操作】  微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】  如何在IIS服务器上快速部署高效网站?  Laravel如何配置和使用缓存?(Redis代码示例)  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  零基础网站服务器架设实战:轻量应用与域名解析配置指南  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  javascript中数组(Array)对象和字符串(String)对象的常用方法总结  Laravel如何使用withoutEvents方法临时禁用模型事件  如何快速登录WAP自助建站平台?  python中快速进行多个字符替换的方法小结  如何实现建站之星域名转发设置?  laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法  如何实现javascript表单验证_正则表达式有哪些实用技巧  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  ,在苏州找工作,上哪个网站比较好?  黑客入侵网站服务器的常见手法有哪些?  Laravel如何使用查询构建器?(Query Builder高级用法)  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  Laravel如何实现API版本控制_Laravel版本化API设计方案  如何在IIS中新建站点并解决端口绑定冲突?  Laravel怎么导出Excel文件_Laravel Excel插件使用教程