java synchronized 锁机制
发布日期:2021-05-20 02:05:32 浏览次数:20 分类:精选文章

本文共 2318 字,大约阅读时间需要 7 分钟。


synchronized(this) vs synchronized(class) 的区别与应用

一、概念

synchronized 是 Java 中的关键字,主要用于通过锁机制实现同步。

synchronized 所带来的锁机制,具有以下两个关键特性:

  • 互斥性:确保在同一时间内,仅有一个线程持有特定对象的锁,实现多线程应用的协调机制。
  • 可见性:确保在释放锁之前,共享变量的修改对后续获取该锁的线程是可见的,避免不一致。

  • 二、对象锁与类锁

    1. 对象锁

    • 每个对象都有一个独立的对象锁(内置锁或 monitor 对象)。
    • 不同对象之间,对象锁是互不干扰的。

    2. 类锁

    • 每个类有一个类锁(Class对象锁)。
    • 不同对象共享同一锁,类锁是通过对象锁实现的。

    三、synchronized 的用法分类

    根据修饰对象分类

    • 修饰方法

      • 非静态方法、静态方法。
    • 修饰代码块

      synchronized (this | object) { … }
      synchronized (类.class) { … }

    根据获取的锁分类

    • 获取对象锁

      synchronized (this | object) { … }
      • 适用于非静态方法和同一对象的操作。
      • 例如:public void method() { synchronized (this) { … } }
    • 获取类锁

      synchronized (类.class) { … }
      • 适用于静态方法和所有同一类的操作。
      • 例如:public static void method() { synchronized (MyClass.class) { … } }

    四、synchronized 用法详解

    1. 获取对象锁

    1.1 对于同一对象

    • 例子:
      class SyncThread implements Runnable {
      @Override
      public void run() {
      if (threadName startsWith "A") {
      async();
      } else if (threadName startsWith "B") {
      sync1();
      }
      }
      private void async() { … }
      private synchronized void sync1() { … }
      }
      • sync1() 方法中 synchronized (this) 获取对象锁,确保线程独占。
      • 非同步代码块和非同步方法可以被并发执行。

    1.2 对于不同对象

    • 例子:
      class SyncThread implements Runnable {
      @Override
      public void run() {
      if (threadName startsWith "A") {
      async();
      } else if (threadName startsWith "B") {
      sync1();
      }
      }
      private void sync(B b) {
      synchronized (b) { … }
      }
      }
      • 同一类的不同对象共享同一锁,依次执行。

    2. 获取类锁

    2.1 对于同一对象

    • 例子:
      class SyncThread implements Runnable {
      @Override
      public void run() {
      if (threadName startsWith "B") {
      sync1();
      } else if (threadName startsWith "C") {
      sync2();
      }
      }
      private synchronized static void sync1() { … }
      }
      • 同一线程内,synchronized (类.class) 获取类锁,确保线程独占。
      • 不同线程共享同一锁,按顺序执行。

    2.2 对于不同对象

    • 例子:
      class SyncThread implements Runnable {
      @Override
      public void run() {
      if (threadName startsWith "A") {
      async();
      } else if (threadName startsWith "C") {
      sync2();
      }
      }
      }
      • 同一类的不同对象共享同一锁,依次执行。

    3. 对象锁与类锁的关系

    • 对象锁:锁定具体对象,同一类的不同对象互不干扰。
    • 类锁:锁定类,同一类的所有对象共享同一锁。
    • 区别:对象锁与类锁作用范围不同,权限范围不同。

    五、补充

  • synchronized 不能继承

    • 子类覆盖非静态 synchronized 方法时,必须重新声明。
  • synchronized 不能在接口定义

    • 只能定义在类方法或代码块。
  • synchronized 不能用于构造方法

    • 但可以使用 synchronized 块实现同步。

  • 这篇文章重新组织了原始内容,删除了无关链接,优化了语言风格,并保留了核心技术内容。

    上一篇:TCP 详解
    下一篇:Docker 中的 Mysql Tomcat 容器时间慢8小时 解决方案

    发表评论

    最新留言

    第一次来,支持一个
    [***.219.124.196]2025年04月16日 01时09分06秒