首页 > 编程语言 >Java中的公平锁和非公平锁

Java中的公平锁和非公平锁

时间:2024-11-22 16:56:19浏览次数:1  
标签:Java Thread lock ReentrantLock 线程 公平 new

公平锁和非公平锁是多线程编程中对锁获取策略的两种不同实现,主要区别在于锁对等待线程的调度方式。


公平锁

公平锁(Fair Lock)遵循 先来先服务 的原则,线程按照请求锁的顺序依次获取锁。

特点

  1. 排队机制

    • 线程请求锁时,如果锁被占用,会进入一个等待队列。

    • 当锁被释放时,队列中等待最久的线程优先获得锁。

  2. 避免线程饥饿

    • 公平锁可以防止某些线程长时间无法获取锁的问题。

  3. 性能较低

    • 排队和唤醒线程的开销较高,可能导致整体性能下降。

实现方式

在 Java 的 ReentrantLock 中,通过将构造方法的参数 fair 设置为 true 来启用公平锁:

ReentrantLock lock = new ReentrantLock(true);

示例

import java.util.concurrent.locks.ReentrantLock;
​
public class FairLockExample {
    private static final ReentrantLock lock = new ReentrantLock(true);
​
    public static void main(String[] args) {
        Runnable task = () -> {
            for (int i = 0; i < 2; i++) {
                lock.lock();
                try {
                    System.out.println(Thread.currentThread().getName() + " got the lock");
                } finally {
                    lock.unlock();
                }
            }
        };
​
        Thread t1 = new Thread(task, "Thread-1");
        Thread t2 = new Thread(task, "Thread-2");
        Thread t3 = new Thread(task, "Thread-3");
​
        t1.start();
        t2.start();
        t3.start();
    }
}

运行结果通常会按照线程的启动顺序依次获取锁,例如:

Thread-1 got the lock
Thread-2 got the lock
Thread-3 got the lock
...

非公平锁

非公平锁(Non-Fair Lock)是默认的锁实现,线程尝试直接竞争锁,不关注排队顺序。

特点

  1. 竞争机制

    • 每个线程都可以直接尝试获取锁,成功则进入临界区,失败则进入等待队列。

  2. 性能较高

    • 由于不需要维护严格的排队顺序,线程调度和唤醒的开销较小,吞吐量更高。

  3. 可能导致线程饥饿

    • 某些线程可能长时间无法获取锁,因为新来的线程可能会插队成功。

实现方式

在 Java 的 ReentrantLock 中,通过将构造方法的参数 fair 设置为 false 或默认值启用非公平锁:

ReentrantLock lock = new ReentrantLock(false);

示例

import java.util.concurrent.locks.ReentrantLock;
​
public class NonFairLockExample {
    private static final ReentrantLock lock = new ReentrantLock();
​
    public static void main(String[] args) {
        Runnable task = () -> {
            for (int i = 0; i < 2; i++) {
                lock.lock();
                try {
                    System.out.println(Thread.currentThread().getName() + " got the lock");
                } finally {
                    lock.unlock();
                }
            }
        };
​
        Thread t1 = new Thread(task, "Thread-1");
        Thread t2 = new Thread(task, "Thread-2");
        Thread t3 = new Thread(task, "Thread-3");
​
        t1.start();
        t2.start();
        t3.start();
    }
}

运行结果可能会出现线程抢占的情况,例如:

Thread-1 got the lock
Thread-3 got the lock
Thread-2 got the lock
Thread-3 got the lock
...

公平锁 vs 非公平锁

特性公平锁非公平锁
锁分配顺序 按线程请求锁的顺序分配 随机分配,允许插队
线程饥饿 不会发生 可能发生
性能 性能较低,开销较大 性能较高,吞吐量大
使用场景 需要严格控制线程公平性 更关注性能,允许一定的不公平性

选择建议

  1. 使用公平锁的场景

    • 需要避免线程饥饿,例如在多线程的资源分配中需要确保所有线程都能公平参与竞争。

  2. 使用非公平锁的场景

    • 更注重性能,线程竞争较少时(如大部分操作锁很快释放),非公平锁的性能优势更明显。

默认情况下,ReentrantLock 使用非公平锁,因为在大多数场景下性能优先于严格的公平性。

标签:Java,Thread,lock,ReentrantLock,线程,公平,new
From: https://www.cnblogs.com/luorongxin/p/18563222

相关文章

  • 【揭秘】JVM类加载器子系统:Java程序员的隐藏武器,你掌握了吗?
    Java虚拟机(JVM)的类加载器子系统是Java平台的核心组件之一,它负责在运行时动态地加载Java类。类加载器子系统通过将类的字节码转换为JVM可以执行的格式,使得Java程序能够实现高度的灵活性和可扩展性。下面将详细解释JVM类加载器子系统的工作原理、结构以及代码示例。打开免费领取......
  • 揭秘JVM性能优化:深入理解运行时数据区,让你的Java应用飞起来!
    Java虚拟机(JVM)的运行时数据区是程序执行期间管理和存储各种信息的关键部分。理解这些区域有助于深入掌握JVM的工作原理和性能优化。以下是对JVM运行时数据区的详细解析:打开免费领取面试资料https://fhos.urlint.cn/cHVLFV一、程序计数器(ProgramCounterRegister)定义:程序计......
  • 基于java和微信小程序实现投票评选系统项目【项目源码+论文说明】计算机毕业设计
    基于java和微信小程序实现投票评选系统演示【内附项目源码+LW说明】摘要越来越多信息化融入到我们生活当中的同时,也在改变着我们的生活和学习方式,当然,变化最明显的除了我们普通民众之外,要数高校学生的生活方式以及校园信息化的变革。智慧是改变生活和生产的一种来源,那么智......
  • Java基础知识(八)
    文章目录异常Exception和Error有什么区别?CheckedException和UncheckedException有什么区别?Throwable类常用方法有哪些?try-catch-finally如何使用?finally中的代码一定会执行吗?如何使用`try-with-resources`代替`try-catch-finally`?异常使用有哪些需要注意的......
  • Java基础知识(七)
    文章目录泛型什么是泛型?有什么作用?泛型的使用方式有哪几种?项目中哪里用到了泛型?反射何谓反射?反射的优缺点?反射的应用场景?注解何谓注解?注解的解析方法有哪几种?SPI何谓SPI?SPI和API有什么区别?SPI的优缺点?序列化和反序列化什么是序列化?什么是反序列化?如果有些字......
  • Java安全-CC链全分析
    前置知识Java访问权限概述对于一个类,其成员(包括成员变量和成员方法)能否被其他类所访问,取决于该成员的修饰词。在Java中,类成员的访问权限修饰词有四个:private,无(包访问权限),protected和public,其权限控制如下表所示:同一个类中同一个包中不同包的子类不同包的无关类public✔......
  • Java 获取本机 IP 地址的方法
    文章目录一、使用InetAddress.getLocalHost二、遍历网络接口获取在Java编程中,若有本机的IP地址的需求,小编来展示一下方法:一、使用InetAddress.getLocalHost一是最基本的获取本机IP地址的方式。示例代码:importjava.net.InetAddress;importjava.net.Un......
  • 项目启动报错java 读取FMavenRepositoryorglz4lz4-java1.7.1lz4-java-1.7.1.jar时出错
    文章目录1.错误呈现2.错误原因3.解决方案3.1方案一:删除jar包,让Maven重新下载(项目重启后可能还是会报错)3.2方案二:删除jar包,手动下载jar包1.错误呈现java:读取F:\MavenRepository\org\lz4\lz4-java\1.7.1\lz4-java-1.7.1.jar时出错;errorinopeningzipfil......
  • 免费送源码:Java+django+MySQL django 教师培训反馈系统 计算机毕业设计原创定制
           目   录摘  要IAbstractII第1章  前  言31.1 研究背景31.2 研究现状31.3 系统开发目标3第2章  系统开发环境62.1HTTP协议62.2HTML网页技术62.3B/S结构62.4django脚本语言72.5MySQL数据库72.6Apache简介8第......
  • Java https validatorException PKIX path building failed 问题处理步骤
    背景这是一个老问题了,其实可以不写,但要花费时间重新整理思绪处理类似的问题很是头疼,因查找的大多数文章只是介绍了其中一部分知识,不能给一个没处理过相关问题的人提供详细步骤,故写此文档。希望大家也能尽可能提供完整的解决方案。原因http升级https时会面临证书校验问题,部......