马士兵java架构师

您现在的位置是:java学习笔记 >

java学习笔记

java互斥锁有哪些

2024-06-05 20:26:22java学习笔记 本文浏览次数:0 百度已收录

本 文 目 录

java互斥锁有哪些
在Java编程中,多线程环境下的资源同步问题一直是开发者需要重点考虑的。互斥锁(Mutex Lock)作为一种同步机制,它能够确保在某一时刻只有一个线程可以访问共享资源。这不仅保证了数据的一致性,还避免了线程间的竞态条件。在Java中,互斥锁的实现主要依赖于java.util.concurrent.locks包中的ReentrantLock类。

互斥锁与同步方法的区别

在Java中,除了互斥锁,还可以通过同步方法或同步代码块来实现线程同步。同步方法使用关键字synchronized来修饰,它会自动获取对象的锁,而同步代码块则需要显式地指定锁定对象。与同步方法相比,互斥锁提供了更高的灵活性,例如尝试非阻塞获取锁(tryLock())、可中断的锁获取(lockInterruptibly())以及超时获取锁(tryLock(long timeout, TimeUnit unit))等功能。

核心类与方法

互斥锁的核心类是ReentrantLock,它实现了Lock接口。以下是一些常用的方法:

  • lock(): 获取锁,如果锁被其他线程持有,则当前线程将被阻塞。
  • unlock(): 释放锁。
  • tryLock(): 尝试获取锁,如果锁不可用则立即返回false
  • lockInterruptibly(): 可中断地获取锁,如果当前线程在获取锁时被中断,则会抛出InterruptedException
  • tryLock(long timeout, TimeUnit unit): 在指定的等待时间内尝试获取锁,如果超时仍未获取到锁,则返回false

使用场景

互斥锁适用于需要更细粒度控制的场景,例如,当多个线程需要访问同一资源,但访问的频率和时间不同,或者需要在获取锁时提供超时机制。此外,互斥锁还可以用于实现公平性(ReentrantLock构造函数中可以指定是否是公平锁)。

代码案例

案例一:基本使用
import java.util.concurrent.locks.ReentrantLock;

public class MutexExample1 {
    private final ReentrantLock lock = new ReentrantLock();

    public void performAction() {
        lock.lock();
        try {
            // 执行需要同步的代码
            System.out.println("Action performed by " + Thread.currentThread().getName());
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        MutexExample1 example = new MutexExample1();
        Thread thread1 = new Thread(() -> example.performAction());
        Thread thread2 = new Thread(() -> example.performAction());
        thread1.start();
        thread2.start();
    }
}

java互斥锁有哪些

案例二:尝试非阻塞获取锁
import java.util.concurrent.locks.ReentrantLock;

public class MutexExample2 {
    private final ReentrantLock lock = new ReentrantLock();

    public boolean performAction() {
        if (lock.tryLock()) {
            try {
                // 执行需要同步的代码
                System.out.println("Action performed by " + Thread.currentThread().getName());
                return true;
            } finally {
                lock.unlock();
            }
        } else {
            System.out.println("Failed to acquire lock");
            return false;
        }
    }

    public static void main(String[] args) {
        MutexExample2 example = new MutexExample2();
        Thread thread1 = new Thread(() -> {
            if (example.performAction()) {
                System.out.println("Thread 1 succeeded");
            }
        });
        Thread thread2 = new Thread(() -> {
            if (example.performAction()) {
                System.out.println("Thread 2 succeeded");
            }
        });
        thread1.start();
        thread2.start();
    }
}

java互斥锁有哪些

表格补充:互斥锁与同步方法的对比

特性 互斥锁(ReentrantLock) 同步方法(synchronized)
可中断性
可超时性
可尝试性
公平性 可配置 不可配置
锁的获取方式 显式 隐式
锁的释放方式 显式 隐式
锁的重入性
锁的实现方式 基于AQS(AbstractQueuedSynchronizer) 基于对象内部锁

通过上述的代码案例和表格对比,我们可以看到互斥锁在Java中的灵活运用,以及它与同步方法的不同之处。互斥锁提供了更多的控制选项,使得开发者可以根据具体的应用场景来选择最合适的同步机制。