详解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日

相关文章

  • jsp页面验证码完整实例

    下面是关于”JSP页面验证码完整实例”的完整攻略: 1. 流程介绍 验证码是一种常见的安全验证,可以有效地防止机器人程序以及恶意攻击。在 JSP 页面中,使用验证码可以有效地保障数据的安全性。 本文将介绍如何在 JSP 页面中实现验证码的功能,包括生成随机验证码、将验证码展示在页面中、验证用户输入的验证码是否正确等。具体流程如下: 用户在页面中填写用户名、密…

    Java 2023年6月15日
    00
  • Tomcat服务器的配置与启动全过程

    以下是Tomcat服务器的配置与启动的完整攻略: 步骤一:下载与安装Tomcat 打开Tomcat的官方网站 https://tomcat.apache.org/,在页面上下载最新版本的Tomcat压缩文件。 下载完成后,解压Tomcat压缩文件到本地磁盘的任意目录下。 步骤二:配置Tomcat环境变量 右键点击开始菜单,选择右侧的“系统”选项。 在弹出的系…

    Java 2023年5月19日
    00
  • Java面试题冲刺第七天–Spring框架1

    下面是Java面试题冲刺第七天–Spring框架1的完整攻略: 一、Spring框架概述 1.1 什么是Spring框架 Spring是一个轻量级的开源Java框架,简化了企业级应用的开发。Spring框架的主要优点在于它对常见的企业应用开发任务(如访问数据库、事务管理、远程调用等)的针对性支持。 1.2 Spring框架的优势 Spring框架降低了Ja…

    Java 2023年5月19日
    00
  • spring data jpa 查询自定义字段,转换为自定义实体方式

    下面是详细的“spring data jpa 查询自定义字段,转换为自定义实体方式”的攻略, 自定义实体类的创建 首先,我们需要手动创建一个自定义实体类来存储查询结果: public class CustomEntity { private Long id; private String name; public CustomEntity(Long id, …

    Java 2023年5月20日
    00
  • 2023-5-6第一次创建博客的第一篇文章

    关于最近学习记下来的一些要点以及模糊的地方总结 对象类型和引用类型可以用链式结构 2进制是toBinaryString 10进制是Decimal 16进制是toHexString 8进制是octal final 1.修饰类 不能被继承 2.修饰方法 不能被重写,能被重载 3.修饰变量 值不可被重新赋值 属性可以被修改 4.修饰引用数据类型 引用对象不能被修改…

    Java 2023年5月6日
    00
  • Java多线程产生死锁的必要条件

    Java多线程产生死锁的必要条件有四个,包括互斥、请求和保持、不可剥夺、环路等待。只有四个条件同时满足,才能导致多线程产生死锁。 互斥 互斥是指当一个线程占用了某个资源,其他的线程就不能再占用该资源。如果在同一时刻有多个线程争夺同一资源,只能有一个线程占用该资源。 请求和保持 请求和保持是指当一个线程保持了某个资源,但同时还需要请求其他资源时,它不会将原有的…

    Java 2023年5月19日
    00
  • 情人节写给女朋友Java Swing代码程序

    下面是详细的“情人节写给女朋友Java Swing代码程序”的攻略: 1. 确定编写目的 首先需要明确编写这个代码的目的是什么,是为了送给女朋友一份特殊的礼物,还是仅仅练习一些Java Swing编程技巧。这个目的确定好以后,就可以开始进入下一步。 2. 设计程序界面 Java Swing是一种操作系统无关的图形界面工具包,可以方便地实现各种界面。在这一步中…

    Java 2023年5月23日
    00
  • 基于Java开发实现ATM系统

    基于Java开发实现ATM系统的完整攻略 ATM系统是一个常见的银行自动化服务系统,能够提供客户便捷的取款、转账、查询等服务。本文将介绍如何使用Java开发一个简单的ATM系统,主要包含以下步骤: 1. 需求分析 在开始开发之前,需要明确该系统的具体需求,包括系统的功能和用户交互方式等。对于ATM系统,我们可以初步确定以下需求: 用户需要能够登录系统,通过录…

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