Java 中的对象锁和类锁有什么区别?


对象锁和类锁都用于在多线程应用程序中实现同步机制。

对象锁

Java 中的每个对象都有一个唯一的锁。如果一个线程想要执行给定对象上的同步方法,首先它必须获得该对象的锁。一旦线程获得了锁,它就可以执行该对象上的任何同步方法。方法执行完成后,线程会自动释放锁。

锁的获取和释放由 JVM 内部处理。当我们想要同步非静态方法或非静态代码块时,对象锁是一种机制,这样只有一个线程能够在类的给定实例上执行代码块。这始终可以用来使实例级数据线程安全。

示例

public class ObjectLevelLockTest implements Runnable {
   @Override
   public void run() {
      objectLock();
   }
   public void objectLock() {
      System.out.println(Thread.currentThread().getName());
      synchronized(this) {
         System.out.println("Synchronized block " + Thread.currentThread().getName());
         System.out.println("Synchronized block " + Thread.currentThread().getName() + " end");
      }
   }
   public static void main(String[] args) {
      ObjectLevelLockTest test1 = new ObjectLevelLockTest();
      Thread t1 = new Thread(test1);
      Thread t2 = new Thread(test1);
      ObjectLevelLockTest test2 = new ObjectLevelLockTest();
      Thread t3 = new Thread(test2);
      t1.setName("t1");
      t2.setName("t2");
      t3.setName("t3");
      t1.start();
      t2.start();
      t3.start();
   }
}

输出

t1
t2
t3
Synchronized block t1
Synchronized block t3
Synchronized block t1 end
Synchronized block t2
Synchronized block t3 end
Synchronized block t2 end

类锁

Java 中的每个类都有一个唯一的锁,它就是类锁。如果一个线程想要执行静态同步方法,则该线程需要类锁。一旦线程获得了类锁,它就可以执行该类的任何静态同步方法。

方法执行完成后,线程会自动释放锁。类锁可以防止多个线程在运行时任何可用实例的同步块中进入。

示例

public class ClassLevelLockTest implements Runnable {
   @Override
   public void run() {
      classLock();
   }
   public void classLock() {
      System.out.println(Thread.currentThread().getName());
      synchronized(ClassLevelLockTest.class) {
         System.out.println("Synchronized block " + Thread.currentThread().getName());
         System.out.println("Synchronized block " + Thread.currentThread().getName() + " end");
      }
   }
   public static void main(String[] args) {
      ClassLevelLockTest test1 = new ClassLevelLockTest();
      Thread t1 = new Thread(test1);
      Thread t2 = new Thread(test1);
      ClassLevelLockTest test2 = new ClassLevelLockTest();
      Thread t3 = new Thread(test2);
      t1.setName("t1");
      t2.setName("t2");
      t3.setName("t3");
      t1.start();
      t2.start();
      t3.start();
   }
}

输出

t1
t2
t3
Synchronized block t1
Synchronized block t1 end
Synchronized block t3
Synchronized block t3 end
Synchronized block t2
Synchronized block t2 end

更新于: 2023-11-28

5K+ 浏览量

开启您的 职业生涯

通过完成课程获得认证

开始学习
广告