ReentrantLock与synchronized的区别
发布人:shili8
发布时间:2025-01-11 22:45
阅读次数:0
**ReentrantLock 与 synchronized 的区别**
在 Java 中,`synchronized` 和 `ReentrantLock` 是两种常见的线程同步机制。虽然它们都可以实现线程安全的访问共享资源,但是它们有着不同的设计理念和使用场景。
###1. synchronized`synchronized` 是 Java 的内置关键字,用于实现线程同步。它通过在方法或代码块上加锁来保证同一时间只有一个线程可以执行该方法或代码块。
**示例代码**
javapublic class SynchronizedExample { private int count =0; public synchronized void increment() { count++; } public static void main(String[] args) throws InterruptedException { SynchronizedExample example = new SynchronizedExample(); Thread thread1 = new Thread(() -> { for (int i =0; i < 10000; i++) { example.increment(); } }); Thread thread2 = new Thread(() -> { for (int i =0; i < 10000; i++) { example.increment(); } }); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(example.count); } }
在这个示例中,我们使用 `synchronized` 关键字来保证 `increment()` 方法的线程安全访问。
###2. ReentrantLock`ReentrantLock` 是 Java 中的一个高级锁类,提供了比 `synchronized` 更灵活和强大的线程同步机制。它可以实现多种锁定策略,例如公平锁、非公平锁等。
**示例代码**
javaimport java.util.concurrent.locks.ReentrantLock; public class ReentrantLockExample { private int count =0; private final ReentrantLock lock = new ReentrantLock(); public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); } } public static void main(String[] args) throws InterruptedException { ReentrantLockExample example = new ReentrantLockExample(); Thread thread1 = new Thread(() -> { for (int i =0; i < 10000; i++) { example.increment(); } }); Thread thread2 = new Thread(() -> { for (int i =0; i < 10000; i++) { example.increment(); } }); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(example.count); } }
在这个示例中,我们使用 `ReentrantLock` 来实现线程安全的访问。
###3. 区别**1. 锁定策略**
`synchronized` 使用的是悲观锁定策略,即每次都加锁,直到方法或代码块执行完毕后才释放锁。这种策略虽然简单,但可能导致性能损失,因为它会阻止其他线程访问共享资源。
`ReentrantLock` 支持多种锁定策略,如公平锁、非公平锁等,可以根据具体场景选择合适的策略。
**2. 锁的粒度**
`synchronized` 的锁粒度是方法或代码块级别的,无法实现更细粒度的锁定。
`ReentrantLock` 支持更细粒度的锁定,如线程、读写锁等,可以根据具体场景选择合适的锁粒度。
**3. 锁的可重入性**
`synchronized` 自动支持可重入性,即同一线程可以多次获得同一个锁,并且每次都能正常工作。
`ReentrantLock` 也支持可重入性,但需要手动实现,通过 `lock()` 和 `unlock()` 方法来控制锁的获取和释放。
**4. 锁的等待**
`synchronized` 不支持锁的等待,即当一个线程尝试获得锁时,如果锁已经被其他线程占用,它会一直等待直到锁被释放。
`ReentrantLock` 支持锁的等待,可以通过 `tryLock()` 方法来尝试获取锁,如果锁已经被其他线程占用,会立即返回 false。
###4. 总结`synchronized` 和 `ReentrantLock` 都可以实现线程安全的访问共享资源,但是它们有着不同的设计理念和使用场景。`synchronized` 使用的是悲观锁定策略,锁粒度是方法或代码块级别的,而 `ReentrantLock` 支持多种锁定策略,如公平锁、非公平锁等,可以根据具体场景选择合适的策略。
在实际开发中,如果需要实现简单的线程安全访问,可以使用 `synchronized`,但如果需要实现更复杂的锁定策略或更细粒度的锁定,可以使用 `ReentrantLock`。