可重入锁
ReentrantLock,synchronized 都是可重入锁。在 Java 中,synchronized 关键字用于实现同步方法和同步代码块,它具有可重入性,允许同一个线程在持有锁的情况下多次获取同一把锁而不会被阻塞。
当一个线程持有一个对象的锁时(无论是通过 synchronized 方法还是 synchronized 代码块),如果再次尝试获取这个对象的锁,它会成功获取而不会被阻塞。这种机制确保了同一个线程可以在执行同步代码块的过程中递归调用该方法或其他同步方法,而不会出现死锁或其他问题。
以下是一个简单的示例来展示 synchronized 的可重入性:
java
public class ReentrantExample {
public synchronized void outer() {
inner();
}
public synchronized void inner() {
System.out.println("Inner method");
}
public static void main(String[] args) {
ReentrantExample example = new ReentrantExample();
example.outer();
}
}
在这个示例中,outer() 方法和 inner() 方法都使用了 synchronized 关键字修饰,这意味着它们都是同步方法。当 outer() 方法调用 inner() 方法时,由于它们都是使用同一把锁(实例对象锁),线程可以顺利地执行内部的同步代码块而不会发生阻塞。这展示了 synchronized 的可重入性特性。
在 Java 中,synchronized 关键字可以用来锁定对象或者类,它们分别对应着不同的锁机制和作用范围。
同步对象锁:当使用 synchronized 关键字修饰一个非静态方法或者代码块时,它会锁定对象实例,即每个对象实例拥有自己的监视器锁。这意味着对于同一个类的不同实例,它们的监视器锁是相互独立的,一个线程可以持有一个对象实例的锁,而不影响其他对象实例的锁。因此,不同的对象实例之间的同步操作是相互独立的。
java
public class Example {
public synchronized void method() {
// 使用 synchronized 锁定对象实例
}
}
同步类锁:当使用 synchronized 关键字修饰一个静态方法或者代码块时,它会锁定整个类的 Class 对象,即该类的所有实例共享同一个监视器锁。这意味着无论该类被实例化多少次,它们都共享一个监视器锁,因此一个线程持有了该类的锁之后,其他线程无法同时获得该类的锁。
java
public class Example {
public static synchronized void staticMethod() {
// 使用 synchronized 锁定类
}
}
总的来说,同步对象锁是针对对象实例的,不同对象实例之间的锁是相互独立的;而同步类锁是针对整个类的,不同对象实例共享同一个类锁。根据具体的需求,可以选择合适的锁机制来进行同步控制,确保多线程环境下数据的安全访问。