ReentrantLock简介说明

欣喜 Java教程 发布时间:2025-03-21 10:40:26 阅读数:17003 1
下文笔者讲述"ReentrantLock简介",如下所示

ReentrantLock简介

  `ReentrantLock`是Java中用于实现可重入锁的一个类
    属于`java.util.concurrent.locks`包
	  ReentrantLock提供比`synchronized`关键字更灵活和强大的锁机制
===============================================================================
`ReentrantLock`是一个可重入的互斥锁
  提供与`synchronized`关键字类似的功能
    但具有更多的灵活性和功能
	 可重入性指同一个线程可以多次获取同一个锁而不会导致死锁

ReentrantLock主要特点

1.可重入性:
   - 同一个线程可以多次获取同一个锁。
   - 通过 `lock()` 方法获取锁
      通过 `unlock()` 方法释放锁。

2. 公平性:
   - 可以选择公平锁(Fair Lock)
      或非公平锁(Non-Fair Lock)
   - 公平锁:线程按照请求锁的顺序获取锁
   - 非公平锁:线程可以插队获取锁,提高吞吐量

3. 条件变量:
   - 支持多个条件变量(`Condition`),
      可以更灵活地控制线程的等待和唤醒。

4. 定时锁:
   - 支持尝试获取锁并在指定时间内等待锁的可用性。

5. 中断响应:
   - 支持中断响应,
      可以在等待锁的过程中响应中断。

ReentrantLock基本用法

1.获取和释放锁

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ReentrantLockExample example = new ReentrantLockExample();

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Final count: " + example.getCount());
    }
}

2.公平锁和非公平锁

import java.util.concurrent.locks.ReentrantLock;

public class FairLockExample {
    private final ReentrantLock fairLock = new ReentrantLock(true); // 公平锁
    private int count = 0;

    public void increment() {
        fairLock.lock();
        try {
            count++;
        } finally {
            fairLock.unlock();
        }
    }

    public int getCount() {
        fairLock.lock();
        try {
            return count;
        } finally {
            fairLock.unlock();
        }
    }

    public static void main(String[] args) {
        FairLockExample example = new FairLockExample();

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Final count: " + example.getCount());
    }
}

3.使用条件变量

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionExample {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    private boolean isReady = false;

    public void awaitReady() {
        lock.lock();
        try {
            while (!isReady) {
                condition.await();
            }
            System.out.println("Thread is ready to proceed.");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }

    public void setReady() {
        lock.lock();
        try {
            isReady = true;
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ConditionExample example = new ConditionExample();

        Thread t1 = new Thread(() -> {
            example.awaitReady();
        });

        Thread t2 = new Thread(() -> {
            example.awaitReady();
        });

        t1.start();
        t2.start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        example.setReady();
    }
}

4.尝试获取锁

import java.util.concurrent.locks.ReentrantLock;

public class TryLockExample {
    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;

    public void increment() {
        if (lock.tryLock()) {
            try {
                count++;
                System.out.println("Lock acquired by " + Thread.currentThread().getName());
            } finally {
                lock.unlock();
            }
        } else {
            System.out.println("Lock not acquired by " + Thread.currentThread().getName());
        }
    }

    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        TryLockExample example = new TryLockExample();

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Final count: " + example.getCount());
    }
}

ReentrantLock优点

1.灵活性:
   - 提供比`synchronized`更灵活锁机制
   - 可以响应中断
     支持定时锁

2.公平性:
   - 可以选择公平锁或非公平锁
      适用于不同的场景

3.条件变量:
   - 支持多个条件变量
      可以更灵活地控制线程的等待和唤醒。

4.可重入性:
   - 同一个线程可以多次获取同一个锁
     避免死锁。

ReentrantLock缺点

1.复杂性:
   - 相比`synchronized`,`ReentrantLock`
      使用更为复杂
	  需要手动管理锁的获取和释放。

2.性能开销:
   - 相比 `synchronized`,`ReentrantLock`
      可能会有一定的性能开销
	   尤其是在高并发场景下

例:使用ReentrantLock实现生产者-消费者模式

使用 `ReentrantLock` 和 `Condition` 
实现生产者-消费者模式的示例
 
import java.util.Linkedlist;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ProducerConsumerExample {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();
    private final Queue<Integer> queue = new LinkedList<>();
    private final int capacity = 10;

    public void produce(int item) {
        lock.lock();
        try {
            while (queue.size() == capacity) {
                notFull.await();
            }
            queue.add(item);
            System.out.println("Produced: " + item);
            notEmpty.signalAll();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }

    public int consume() {
        lock.lock();
        try {
            while (queue.isEmpty()) {
                notEmpty.await();
            }
            int item = queue.poll();
            System.out.println("Consumed: " + item);
            notFull.signalAll();
            return item;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return -1;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ProducerConsumerExample example = new ProducerConsumerExample();

        Thread producer = new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                example.produce(i);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                example.consume();
                try {
                    Thread.sleep(150);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        producer.start();
        consumer.start();
    }
}

代码说明

1.定义锁和条件变量:
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();
    private final Queue<Integer> queue = new LinkedList<>();
    private final int capacity = 10;

2.生产者方法:
 
    public void produce(int item) {
        lock.lock();
        try {
            while (queue.size() == capacity) {
                notFull.await();
            }
            queue.add(item);
            System.out.println("Produced: " + item);
            notEmpty.signalAll();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
   
    - 获取锁:`lock.lock()`
    - 等待条件:如果队列已满,调用 `notFull.await()` 等待。
    - 添加元素:将元素添加到队列中。
    - 唤醒等待线程:调用 `notEmpty.signalAll()` 
	    唤醒所有等待的消费者线程。
    - 释放锁:`lock.unlock()`

3.消费者方法:
    public int consume() {
         
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaCourse/202503/8384.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者