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

相关文章

  • Java基础之代码死循环详解

    Java基础之代码死循环详解 简介 代码死循环是指在程序运行过程中,因为某些原因造成程序不停地重复执行某一段代码的现象。死循环通常是因为程序设计不合理或者编写错误所导致的,如果长时间不会自动退出,会造成计算机死机或者卡死。代码死循环是编写程序时需要避免的错误。 常见死循环 for循环死循环 for(int i=0; i>=0; i++){ System…

    Java 2023年5月20日
    00
  • Java的Struts框架报错“ChainNotFoundException”的原因与解决办法

    当使用Java的Struts框架时,可能会遇到“ChainNotFoundException”错误。这个错误通常由以下原因之一起: 配置错误:如果配置文件中没有正确配置ActionChain,则可能会出现此。在这种情况下,需要检查配置文件以解决此问题。 类路径问题:如果类路径不正确,则可能会出现此。在种情况下,需要检查类路径以解决此问题。 以下是两个实例: …

    Java 2023年5月5日
    00
  • Springboot轻量级的监控组件SpringbootAdmin

    让我来为你详细讲解一下“Springboot轻量级的监控组件SpringbootAdmin”的完整攻略。 什么是SpringbootAdmin? SpringbootAdmin是一款开源的轻量级的监控组件,它可以实时监控Spring Boot应用程序的状态、指标和环境,同时还可以提供一些管理和监控功能,比如重启应用程序、查看日志等等。 如何使用Springb…

    Java 2023年5月15日
    00
  • Java 切割字符串的几种方式集合

    Java 切割字符串的几种方式集合 在Java中,切割字符串是非常常见的操作。本文将介绍Java中切割字符串的几种方式,包括使用StringTokenizer、split()函数和正则表达式等。 使用StringTokenizer java.util.StringTokenizer类是Java内置用来分割字符串的类,它可以将一个字符串按照指定的分隔符进行分割…

    Java 2023年5月26日
    00
  • ajax jquery实现页面某一个div的刷新效果

    下面我就来详细讲解一下“ajax jquery实现页面某一个div的刷新效果”的完整攻略: 1. 理解 AJAX 在使用 AJAX 前,我们需要先理解什么是 AJAX。AJAX 全称是 Asynchronous JavaScript and XML,翻译过来是“异步 JavaScript 和 XML”。它是一种用于创建快速动态网页的技术,允许在不重新加载整个…

    Java 2023年6月15日
    00
  • Java源码刨析之ArrayQueue

    Java源码刨析之ArrayQueue攻略 前言 在这篇文章中,我们将深入探究Java中ArrayQueue的实现原理。ArrayQueue是一种基于数组实现的队列,它的特点是入队和出队的时间复杂度均为O(1),空间复杂度为O(n)。其实现原理对于Java初学者而言可能略显复杂,但理解了其原理就可以举一反三,掌握更多队列的实现方式。 代码分析 数据结构 Ar…

    Java 2023年5月26日
    00
  • java通过AES生成公钥加密数据ECC加密公钥

    下面将详细讲解怎样通过java使用AES算法生成公钥加密数据并使用ECC加密公钥,作为完整攻略。这个过程叙述包括生成密钥对、使用AES算法对数据进行加密、使用ECC加密公钥保护AES密钥、将加密数据和加密密钥存储到文件中等多个步骤。 1. 生成ECC密钥对 我们可以使用Java标准库中的KeyPairGenerator类来生成ECC密钥对。下面是示例代码: …

    Java 2023年5月20日
    00
  • 基于java中的流程控制语句总结(必看篇)

    基于Java中的流程控制语句总结(必看篇) 概述 在Java中,流程控制语句是指程序员可以通过使用一些关键字和语法来控制流程的执行顺序,使得程序能够根据不同的条件或者需求,动态控制流程的执行。Java中的流程控制语句包括分支语句和循环语句。 分支语句 Java中的分支语句主要有if-else和switch两种。 if-else语句 if-else语句是Jav…

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