Java多线程中的互斥锁解析

 更新时间:2023年09月15日 11:06:07   作者:伊颦伊笑  
这篇文章主要介绍了Java多线程中的互斥锁解析,Java语言中,引入了对象互斥锁的概念,来保证共享数据操作的完整性,每个对象都对应于一个可称为互斥锁的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象,需要的朋友可以参考下

基本介绍

  1. Java语言中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。
  2. 每个对象都对应于一个可称为 “ 互斥锁 ” 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
  3. 关键字 synchronized 来与对象的互斥锁联系。当某个对象用 synchronized 修饰时,表明该对象在任一时刻只能由一个线程访问
  4. 同步的局限性:导致程序的执行效率要降低
  5. 同步方法(非静态的)的锁可以是this,也可以是其他对象(要求是同一个对象)
  6. 同步方法(静态的)的锁为当前类本身。

把 synchronized 写在代码块上

package thread_;
/**
 * @Author: Gin
 * @Description:
 * @Modified By: Gin
 * @Date: Created in 16:37 2021/9/27
 */
public class Thread11 {
    public static void main(String[] args) {
        SellThread04 sellThread04 = new SellThread04();
        new Thread(sellThread04).start();
        new Thread(sellThread04).start();
        new Thread(sellThread04).start();
    }
}
class SellThread04 implements Runnable{
    private int ticketsNum = 100;
    private boolean flag = true;
    @Override
    public void run() {
        while (flag) {
            sell();
        }
    }
    /*
        1. public synchronized void sell(){} 就是一个同步方法
        2. 这时“锁”在 this 对象上
        3. 也可以在代码块上写 synchronized,同步代码块,互斥锁还是在 this 对象上
           如下:
     */
    public /* synchronized */ void sell(){
        synchronized (this) {
            if(ticketsNum <= 0){
                System.out.println("售票结束...");
                flag = false;
                return;
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口 " + Thread.currentThread().getName() + " 售票一张, 剩余票数 " + (--ticketsNum));
        }
    }
}

测试操作同一个对象、静态方法的锁的添加

package thread_;
/**
 * @Author: Gin
 * @Description:
 * @Modified By: Gin
 * @Date: Created in 16:37 2021/9/27
 */
public class Thread11 {
    public static void main(String[] args) {
        SellThread04 sellThread04 = new SellThread04();
        new Thread(sellThread04).start();
        new Thread(sellThread04).start();
        new Thread(sellThread04).start();
    }
}
class SellThread04 implements Runnable{
    private int ticketsNum = 100;
    private boolean flag = true;
    // 同步方法(非静态的)的锁可以是this,也可以是其他对象(要求是同一个对象)
    // new 一个 Object 对象,测试操作同一个对象
    Object object = new Object();
    // 同步方法(静态的)的锁为当前类本身。
    public synchronized static void m1(){
        System.out.println("m1");
    }
    // 在静态方法中实现一个同步代码块
    public static void m2(){
        synchronized (SellThread04.class) {
            System.out.println("m2");
        }
    }
    @Override
    public void run() {
        while (flag) {
            sell();
        }
    }
    /*
        1. public synchronized void sell(){} 就是一个同步方法
        2. 这时“锁”在 this 对象上
        3. 也可以在代码块上写 synchronized,同步代码块,互斥锁还是在 this 对象上
           如下:
     */
    public /* synchronized */ void sell(){
        synchronized ( /*this*/ object ) { // 测试操作同一个对象
            if(ticketsNum <= 0){
                System.out.println("售票结束...");
                flag = false;
                return;
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口 " + Thread.currentThread().getName() + " 售票一张, 剩余票数 " + (--ticketsNum));
        }
    }
}

细节

同步方法如果没有使用 static 修饰:默认锁对象为 this如果方法使用 static 修饰,默认锁对象:当前类.class

到此这篇关于Java多线程中的互斥锁解析的文章就介绍到这了,更多相关Java互斥锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现简单的银行管理系统的示例代码

    Java实现简单的银行管理系统的示例代码

    这篇文章主要介绍了如何利用Java实现简单的银行管理系统,可以实现存款,取款,查询等功能,文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-09-09
  • MyBatis异常-Property ''configLocation'' not specified, using default MyBatis Configuration

    MyBatis异常-Property ''configLocation'' not specified, using d

    今天小编就为大家分享一篇关于MyBatis异常-Property 'configLocation' not specified, using default MyBatis Configuration,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • 深入浅析SPI机制在JDK与Spring Boot中的应用

    深入浅析SPI机制在JDK与Spring Boot中的应用

    SPI是一种使软件框架或库更加模块化、可扩展和可维护的有效方法。通过遵循“开闭原则”, SPI 确保了系统的稳定性和灵活性,从而满足了不断变化的业务需求,这篇文章主要介绍了SPI机制在JDK与Spring Boot中的应用,需要的朋友可以参考下
    2023-09-09
  • java基于dom4j包实现对XML解析的方法

    java基于dom4j包实现对XML解析的方法

    这篇文章主要介绍了java基于dom4j包实现对XML解析的方法,结合实例形式分析了java针对xml格式数据的相关解析操作实现技巧,需要的朋友可以参考下
    2017-05-05
  • Springboot 多module打包方案示例详解

    Springboot 多module打包方案示例详解

    在使用Springboot进行多模块项目开发时,可能会遇到模块间依赖不存在的问题,本文介绍了两种主要的解决方案,这些方法有助于生成可执行的jar包,并确保模块间正确依赖,适用于多层项目结构中的有效管理和打包,感兴趣的朋友跟随小编一起看看吧
    2023-07-07
  • MyBatis-plus使用lambda条件构造器报错问题及解决

    MyBatis-plus使用lambda条件构造器报错问题及解决

    这篇文章主要介绍了MyBatis-plus使用lambda条件构造器报错问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 深入剖析Java中的synchronized关键字

    深入剖析Java中的synchronized关键字

    在 Java 程序中,我们可以利用 synchronized 关键字来对程序进行加锁,它既可以用来声明一个 synchronized 代码块,也可以直接标记静态方法或者实例方法,本文就带大家深入了解Java中的synchronized关键字,感兴趣的同学可以参考阅读
    2023-06-06
  • springboot手写一个自己的starter源码

    springboot手写一个自己的starter源码

    在本篇文章里小编给大家整理了关于springboot手写一个自己的starter源码的全部知识点内容,需要的朋友们学习下。
    2019-06-06
  • Java多线程ThreadPoolExecutor详解

    Java多线程ThreadPoolExecutor详解

    这篇文章主要介绍了Java多线程ThreadPoolExecutor详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • lombok注解@Data使用在继承类上时出现警告的问题及解决

    lombok注解@Data使用在继承类上时出现警告的问题及解决

    Lombok的@Data注解简化了实体类代码,但在子类中使用时会出现警告,指出equals和hashCode方法不会考虑父类属性,解决方法有两种:一是在父类上使用@EqualsAndHashCode(callSuper=true)注解;二是通过配置lombok.config文件,均能有效解决警告问题
    2024-10-10

最新评论