详解java 对象锁与类锁

我们来详细讲解一下 Java 对象锁和类锁。

什么是对象锁?

在 Java 中,每一个对象都有一个锁,也就是监视器锁(Monitor Lock)。当一个线程访问某个对象的 synchronized 方法或 synchronized 块时,这个线程会试图获得这个对象的锁。获得对象锁后,这个线程才能进入 synchronized 方法或 synchronized 块中执行代码。其他线程必须等待锁的释放才能继续执行。

一个对象锁只保护一个对象的同步方法或同步块。如果一个对象有多个同步方法,每个方法都可以被独立执行,因为每个方法都有自己的对象锁。如果一个线程正在执行某个对象的同步方法,其他线程可以访问该对象的非同步方法,因为这些非同步方法没有竞争这个对象锁。

下面是一个简单的示例代码,通过 synchronized 关键字实现了线程之间的同步:

public class MyThread extends Thread {
    private String threadName;
    private Object object;

    public MyThread(String name, Object obj) {
        threadName = name;
        object = obj;
    }

    public void run() {
        synchronized(object) {
            System.out.println(threadName + " has acquired the object lock.");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
            System.out.println(threadName + " is releasing the object lock.");
        }
    }

    public static void main(String[] args) {
        Object obj = new Object();
        MyThread t1 = new MyThread("Thread 1", obj);
        MyThread t2 = new MyThread("Thread 2", obj);
        t1.start();
        t2.start();
    }
}

运行上面的代码,你会发现 Thread 1 和 Thread 2 交替获得和释放了 obj 这个对象的锁。

什么是类锁?

除了对象锁以外,Java 还有一种锁叫做类锁(Class Lock)。当一个线程访问某个类的 synchronized 静态方法或 synchronized(classname) 代码块时,这个线程会获得这个类的 Class 对象的锁。类锁只有一个,因此多个线程访问类的 synchronized 静态方法或 synchronized(classname) 代码块时会相互竞争,而不同的类的 synchronized 静态方法或 synchronized(不同的Class对象) 代码块之间没有竞争关系。

和对象锁一样,类锁也是可重入的,也就是说一个线程已经获得了某个类的锁,那么它可以重复获得该锁,而不用重新等待锁的释放。

下面是一个示例代码,演示了如何使用类锁:

public class ThreadSafeCounter {
    private static int count = 0;

    public static synchronized void increment() {
        System.out.println(Thread.currentThread().getName() + " is running increment().");
        int temp = count;
        temp++;
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        count = temp;
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            ThreadSafeCounter.increment();
        });
        Thread t2 = new Thread(() -> {
            ThreadSafeCounter.increment();
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("The final count is " + count);
    }
}

在上面的示例代码中,我们定义了一个静态方法 increment(),使用 synchronized 关键字修饰,实现了对 count 变量的线程安全访问。在 main 方法中,我们启动了两个线程对 count 变量进行自增操作,由于 increment() 方法使用的是类锁,所以两个线程会相互竞争,保证了对 count 变量的线程安全访问。

通过这两个示例,我们可以更好地理解对象锁和类锁在 Java 中的应用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解java 对象锁与类锁 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • 类加载的生命周期包括哪些阶段?

    以下是关于类加载的生命周期包括哪些阶段的详细讲解: 类加载的生命周期包括哪些阶段? 类加载的生命周期包括以下几个阶段: 加载(Loading):将类的字码加载到内存中。 链接(Linking):将类的二进制数据合并到 Java 运行时环境中。 验证(Verification):验证的字节码是否符合 Java 虚拟机规范。 准备(Preparation):为类…

    Java 2023年5月12日
    00
  • ubuntu 14.04 安装 apache ant教程

    Ubuntu 14.04 安装 Apache Ant教程 Apache Ant是Apache软件基金会的一个软件项目,是一款Java开发工具,主要用于Java应用程序的自动化构建和部署。 系统要求 Ubuntu 14.04操作系统 Java JDK 1.7或1.8 安装步骤 安装Java 首先,安装Java JDK 1.7或1.8。在终端中输入以下命令: s…

    Java 2023年6月2日
    00
  • Spring MVC简介_动力节点Java学院整理

    Spring MVC简介 Spring MVC是一种基于Java的轻量级Web框架,用于开发Web应用程序。它基于MVC(模型-视图-控制器)设计模式,该模式将应用程序分为三个主要组成部分,以提供松散耦合的应用程序开发。Spring MVC还提供了中央调度,以便将控制器(Controller)与用户界面(View)分开。 Spring MVC架构 Sprin…

    Java 2023年5月31日
    00
  • 学习Java中Class类及其用法

    学习 Java 中 Class 类及其用法 什么是 Class 类 在 Java 中,每个对象都有与之相关联的 Class 类。可以将 Class 看作是一份对象的“说明书”,里面包含着这个对象的所有属性和方法。 在 Java 中,可以使用 getClass() 方法来获取一个对象的 Class 类,也可以使用 .class 来获取某个类的 Class 类。…

    Java 2023年5月26日
    00
  • Spring钩子接口汇总分析使用示例

    Spring钩子接口汇总分析使用示例 什么是Spring钩子接口? Spring钩子接口,也称为Spring钩子函数,是用于Spring容器生命周期中的扩展点。这些接口允许开发人员在特定生命周期事件上执行代码。Spring钩子接口提供了许多方法来覆盖各种通知事件,例如Bean初始化、Bean销毁等。 Spring钩子接口汇总 Spring Framework…

    Java 2023年5月19日
    00
  • Spring jackson原理及基本使用方法详解

    Spring Jackson原理及基本使用方法详解 什么是Jackson? Jackson是一个开源的Java库,用于处理JSON格式的文本数据。它可以将Java对象序列化为JSON格式的数据,也可以将JSON格式的数据反序列化为Java对象。 什么是Spring Jackson? Spring Jackson是Spring框架中对Jackson的集成。通过…

    Java 2023年5月26日
    00
  • 详解Java二叉排序树

    详解Java二叉排序树 什么是二叉排序树 二叉排序树是一种特殊的二叉树,它满足如下条件: 左子树上所有节点的值均小于它的根节点的值。 右子树上所有节点的值均大于它的根节点的值。 左、右子树也分别为二叉排序树。 二叉排序树可以使用它的特殊性质进行快速查找、插入、删除等操作。 实现二叉排序树 实现二叉排序树需要定义二叉树节点类以及二叉排序树类: class No…

    Java 2023年5月19日
    00
  • 详解使用@RequestBody取POST方式的json字符串

    下面我将详细讲解使用@RequestBody取POST方式的json字符串的完整攻略。 什么是@RequestBody @RequestBody 是Spring框架提供的注解,通常用于接收前端传来的JSON格式的数据。在处理来自前端的POST请求时,Spring会自动解析标有@RequestBody 注解的参数,并将请求体中的JSON字符串转换为对应的Jav…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部