博客
关于我
Java高并发系列(读书笔记)——关键字synchronized的功能扩展:重入锁
阅读量:273 次
发布时间:2019-03-01

本文共 4084 字,大约阅读时间需要 13 分钟。

重新优化后的内容

重入锁的优势与特点

重入锁(Reentrant Lock)是Java并发编程中一种高级的同步机制,主要用于解决多线程程序中共享资源的竞态问题。相比于传统的synchronized关键字,重入锁在性能上有显著提升,尤其是在处理中断和限时等待需求时更加灵活。重入锁通过其内部基于队列的机制,能够更好地管理线程的等待和中断流程。

重入锁的核心方法

重入锁主要通过几个关键方法实现其功能:

  • lock():尝试获取锁,如果锁已被占用,则进入等待状态,直到锁被释放或中断。
  • lockInterruptibly():获取锁,并优先处理中断信号。如果当前线程正在等待锁,中断信号会立即被处理,锁的获取流程会停止。
  • tryLock():尝试获取锁,不进入等待状态。如果锁已被占用,立即返回false,否则返回true,并立即释放锁。
  • unlock():释放锁,允许其他线程获取锁。
  • 重入锁的默认实现类ReentrantLock,以及其扩展类ReentrantLock(boolean fair),能够支持公平锁和非公平锁的模式,后者是默认设置。

    重入锁的实际应用

    临界区保护与线程安全

    以下是一个使用重入锁保护临界区资源的典型示例:

    public class ReenterLock implements Runnable {    private static final ReentrantLock lock = new ReentrantLock();    private static int count = 0;    @Override    public void run() {        for (int i = 0; i < 10000000; i++) {            lock.lock();            try {                count++;            } finally {                lock.unlock();            }        }    }    public static void main(String[] args) throws InterruptedException {        ReenterLock task = new ReenterLock();        Thread t1 = new Thread(task);        Thread t2 = new Thread(task);        t1.start();        t2.start();        t1.join();        t2.join();        System.out.println("总次数 = " + count);    }}
    中断处理的能力

    重入锁支持中断机制,可以在等待锁的过程中被中断,这对于解决死锁问题或优化资源利用非常有用。以下是一个典型的死锁案例及其解决方案:

    public class IntLock implements Runnable {    private static final ReentrantLock lock1 = new ReentrantLock();    private static final ReentrantLock lock2 = new ReentrantLock();    private int currentLock;    public IntLock(int lock) {        this.currentLock = lock;    }    @Override    public void run() {        try {            if (currentLock == 1) {                lock1.lockInterruptibly();                Thread.sleep(500);                lock2.lockInterruptibly();            } else {                lock2.lockInterruptibly();                Thread.sleep(500);                lock1.lockInterruptibly();            }        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            if (lock1.isHeldByCurrentThread()) {                lock1.unlock();            }            if (lock2.isHeldByCurrentThread()) {                lock2.unlock();            }            System.out.println(Thread.currentThread().getId() + ":线程退出");        }    }    public static void main(String[] args) throws InterruptedException {        IntLock task = new IntLock(1);        Thread t1 = new Thread(task);        Thread t2 = new Thread(task);        t1.start();        t2.start();        Thread.sleep(1000);        t2.interrupt();    }}
    限时等待与资源释放

    重入锁支持tryLock(long timeout, TimeUnit unit)方法,允许线程在指定的时间内尝试获取锁,避免长时间等待。以下是一个使用限时锁的示例:

    public class TimeLock implements Runnable {    private static final ReentrantLock lock = new ReentrantLock();    @Override    public void run() {        boolean locked = lock.tryLock(5, TimeUnit.SECONDS);        if (locked) {            Thread.sleep(6000);        } else {            System.out.println("无法获取锁");        }    }    public static void main(String[] args) {        TimeLock task = new TimeLock();        Thread t1 = new Thread(task);        Thread t2 = new Thread(task);        t1.start();        t2.start();    }}

    公平锁的实现

    重入锁支持公平锁模式,通过构造函数ReentrantLock(boolean fair)可以指定锁的公平性。公平锁确保同一资源的竞争按照线程启动的先后顺序进行,避免了饥饿现象。以下是一个公平锁的使用示例:

    public class FairLock implements Runnable {    private static final ReentrantLock lock = new ReentrantLock(true);    @Override    public void run() {        while (true) {            lock.lock();            System.out.println(Thread.currentThread().getName() + "获得锁");            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }    }    public static void main(String[] args) {        FairLock task = new FairLock();        Thread t1 = new Thread(task, "Thread_t1");        Thread t2 = new Thread(task, "Thread_t2");        t1.start();        t2.start();    }}

    总结

    重入锁通过其灵活的锁定机制、强大的中断能力以及支持公平锁和限时等待功能,为现代Java程序的多线程编程提供了强大的工具。在实际应用中,重入锁可以有效避免死锁、减少等待时间,并优化资源利用效率。

    转载地址:http://hqjo.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现四阶龙格库塔法(附完整源码)
    查看>>
    Objective-C实现四阶龙格库塔法(附完整源码)
    查看>>
    Objective-C实现回调实例(附完整源码)
    查看>>
    Objective-C实现图-弗洛伊德FloydWarshall算法(附完整源码)
    查看>>
    Objective-C实现图书借阅系统(附完整源码)
    查看>>
    Objective-C实现图像二维熵的图像信号丢失检测(附完整源码)
    查看>>
    Objective-C实现图像去雾算法(附完整源码)
    查看>>
    Objective-C实现图像灰度变换(附完整源码)
    查看>>
    Objective-C实现图像相似度平均值哈希算法(附完整源码)
    查看>>
    Objective-C实现图像相似度平均值哈希算法(附完整源码)
    查看>>
    Objective-C实现图像移动(附完整源码)
    查看>>
    Objective-C实现图层混合算法(附完整源码)
    查看>>
    Objective-C实现图形着色算法(附完整源码)
    查看>>
    Objective-C实现图片dilation operation扩张操作算法(附完整源码)
    查看>>
    Objective-C实现图片erosion operation侵蚀操作算法(附完整源码)
    查看>>
    Objective-C实现图片的放大缩小(附完整源码)
    查看>>
    Objective-C实现图片腐蚀(附完整源码)
    查看>>
    Objective-C实现图片膨胀(附完整源码)
    查看>>
    Objective-C实现图片转化为 ASCII图(附完整源码)
    查看>>
    Objective-C实现图的邻接矩阵(附完整源码)
    查看>>