Java可重入锁案例

wen java案例 4

本文目录导读:

Java可重入锁案例

  1. 基础可重入锁案例
  2. 高级特性案例
  3. 生产者消费者案例
  4. 锁超时与中断处理案例
  5. 注意事项

我将为您展示一个完整的Java可重入锁(ReentrantLock)案例,包含基本用法和高级特性。

基础可重入锁案例

import java.util.concurrent.locks.ReentrantLock;
public class BasicReentrantLockDemo {
    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;
    // 基本加锁和解锁
    public void increment() {
        lock.lock();
        try {
            count++;
            System.out.println(Thread.currentThread().getName() + " - count: " + count);
        } finally {
            lock.unlock();
        }
    }
    // 可重入性演示:同一个线程可以多次获取锁
    public void reentrantMethod() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " - 第一次获取锁");
            // 再次获取同一把锁
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " - 第二次获取锁(重入)");
            } finally {
                lock.unlock();
            }
        } finally {
            lock.unlock();
        }
    }
    public static void main(String[] args) {
        BasicReentrantLockDemo demo = new BasicReentrantLockDemo();
        // 演示可重入性
        demo.reentrantMethod();
        // 多线程竞争
        Runnable task = () -> {
            for (int i = 0; i < 3; i++) {
                demo.increment();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread t1 = new Thread(task, "Thread-1");
        Thread t2 = new Thread(task, "Thread-2");
        t1.start();
        t2.start();
    }
}

高级特性案例

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class AdvancedReentrantLockDemo {
    private final ReentrantLock fairLock = new ReentrantLock(true);  // 公平锁
    private final ReentrantLock unfairLock = new ReentrantLock();   // 非公平锁(默认)
    // 可中断锁
    public void interruptibleLock() throws InterruptedException {
        ReentrantLock lock = new ReentrantLock();
        Thread t1 = new Thread(() -> {
            lock.lock();
            try {
                System.out.println("Thread-1 获取锁,正在执行...");
                Thread.sleep(5000); // 模拟长时间任务
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                System.out.println("Thread-1 释放锁");
            }
        });
        Thread t2 = new Thread(() -> {
            try {
                System.out.println("Thread-2 尝试获取锁(可中断)");
                lock.lockInterruptibly();
                try {
                    System.out.println("Thread-2 成功获取锁");
                } finally {
                    lock.unlock();
                }
            } catch (InterruptedException e) {
                System.out.println("Thread-2 被中断");
            }
        });
        t1.start();
        Thread.sleep(100);
        t2.start();
        Thread.sleep(100);
        // 中断 t2
        t2.interrupt();
    }
    // 尝试获取锁(非阻塞)
    public void tryLockDemo() {
        ReentrantLock lock = new ReentrantLock();
        // 尝试获取锁,如果获取不到立即返回
        if (lock.tryLock()) {
            try {
                System.out.println("成功获取锁");
                // 执行任务
            } finally {
                lock.unlock();
            }
        } else {
            System.out.println("锁被其他线程持有");
        }
        // 尝试获取锁,等待指定时间
        try {
            if (lock.tryLock(3, TimeUnit.SECONDS)) {
                try {
                    System.out.println("在3秒内成功获取锁");
                } finally {
                    lock.unlock();
                }
            } else {
                System.out.println("3秒内未获取到锁");
            }
        } catch (InterruptedException e) {
            System.out.println("获取锁时被中断");
        }
    }
    // 公平锁与非公平锁对比
    public void fairLockDemo() {
        Runnable task = () -> {
            for (int i = 0; i < 3; i++) {
                fairLock.lock();
                try {
                    System.out.println(Thread.currentThread().getName() + " 获取公平锁");
                } finally {
                    fairLock.unlock();
                }
                unfairLock.lock();
                try {
                    System.out.println(Thread.currentThread().getName() + " 获取非公平锁");
                } finally {
                    unfairLock.unlock();
                }
            }
        };
        Thread[] threads = new Thread[5];
        for (int i = 0; i < 5; i++) {
            threads[i] = new Thread(task, "Thread-" + (i + 1));
            threads[i].start();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        AdvancedReentrantLockDemo demo = new AdvancedReentrantLockDemo();
        System.out.println("=== 可中断锁演示 ===");
        demo.interruptibleLock();
        Thread.sleep(6000);
        System.out.println("\n=== 尝试获取锁演示 ===");
        demo.tryLockDemo();
        System.out.println("\n=== 公平锁与非公平锁演示 ===");
        demo.fairLockDemo();
    }
}

生产者消费者案例

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ProducerConsumerDemo {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notEmpty = lock.newCondition();
    private final Condition notFull = lock.newCondition();
    private final Queue<Integer> queue = new LinkedList<>();
    private final int MAX_SIZE = 5;
    private int count = 0;
    // 生产者
    public void produce() {
        lock.lock();
        try {
            while (queue.size() == MAX_SIZE) {
                System.out.println("队列已满,生产者等待...");
                notFull.await(); // 等待队列不满
            }
            int value = ++count;
            queue.offer(value);
            System.out.println(Thread.currentThread().getName() + " 生产: " + value);
            notEmpty.signal(); // 通知消费者可以消费了
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
    // 消费者
    public void consume() {
        lock.lock();
        try {
            while (queue.isEmpty()) {
                System.out.println("队列为空,消费者等待...");
                notEmpty.await(); // 等待队列不空
            }
            int value = queue.poll();
            System.out.println(Thread.currentThread().getName() + " 消费: " + value);
            notFull.signal(); // 通知生产者可以生产了
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
    public static void main(String[] args) {
        ProducerConsumerDemo demo = new ProducerConsumerDemo();
        // 启动生产者线程
        Runnable producerTask = () -> {
            for (int i = 0; i < 10; i++) {
                demo.produce();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        // 启动消费者线程
        Runnable consumerTask = () -> {
            for (int i = 0; i < 10; i++) {
                demo.consume();
                try {
                    Thread.sleep(150);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread producer1 = new Thread(producerTask, "Producer-1");
        Thread producer2 = new Thread(producerTask, "Producer-2");
        Thread consumer1 = new Thread(consumerTask, "Consumer-1");
        Thread consumer2 = new Thread(consumerTask, "Consumer-2");
        producer1.start();
        producer2.start();
        consumer1.start();
        consumer2.start();
    }
}

锁超时与中断处理案例

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class LockTimeoutDemo {
    private final ReentrantLock lock = new ReentrantLock();
    public void performTask() {
        try {
            // 尝试获取锁,最多等待2秒
            if (lock.tryLock(2, TimeUnit.SECONDS)) {
                try {
                    System.out.println(Thread.currentThread().getName() + " 获取锁成功");
                    Thread.sleep(3000); // 模拟长时间任务
                } finally {
                    lock.unlock();
                    System.out.println(Thread.currentThread().getName() + " 释放锁");
                }
            } else {
                System.out.println(Thread.currentThread().getName() + " 等待超时,放弃执行");
            }
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + " 被中断");
        }
    }
    public static void main(String[] args) throws InterruptedException {
        LockTimeoutDemo demo = new LockTimeoutDemo();
        // 线程1获取锁并执行任务
        Thread t1 = new Thread(() -> demo.performTask(), "Thread-1");
        // 线程2尝试获取锁
        Thread t2 = new Thread(() -> demo.performTask(), "Thread-2");
        t1.start();
        Thread.sleep(100); // 确保Thread-1先获取锁
        t2.start();
    }
}
  1. 可重入性:同一个线程可以多次获取同一把锁
  2. 公平性:可以指定公平锁(先来先服务)或非公平锁
  3. 可中断:支持中断等待中的线程
  4. 超时机制:支持tryLock带超时时间
  5. 条件变量:通过Condition实现复杂的线程同步

注意事项

  • 使用lock()后一定要在finally中释放锁
  • 优先使用tryLock()避免死锁
  • 根据场景选择合适的锁类型(公平/非公平)
  • 合理使用中断处理,保持线程的可响应性

这些案例涵盖了ReentrantLock的主要使用场景,可以根据实际需求选择合适的实现方式。

抱歉,评论功能暂时关闭!