Lock的公平锁与非公平锁

注:lock是可重入锁

lock锁分为两类:公平锁和非公平锁。按照本人的理解,公平锁指的是在多个线程同时获取锁时,会按照该线程的请求先后顺序来决定哪个线程优先获取到锁(即:根据同步队列中的线程顺序来决定),非公平锁则是自由竞争,和线程的等待时间无关。

而且非公平锁可能出现一个线程连续获取锁的现象(原因是当一个线程请求锁时,只要获取了同步状态即成功获取锁。在这个前提下,刚释放的线程再次获取同步状态的几率非常大)

package com.zhl.practice;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Holley
 * @Description 公平锁与非公平锁的演示
 * @create 2019-05-16 10:16
 **/
public class LockTest {

    private static ReenTrantLock2 fairLock = new ReenTrantLock2(true);

    private static ReenTrantLock2 nonfairLock = new ReenTrantLock2(false);

    @Test
    public void fair(){
        testLock(fairLock);
    }

    @Test
    public void unfair(){
        testLock(nonfairLock);
    }

    private void testLock(ReenTrantLock2 lock){
        for(int i = 0; i<5;i++){
            Job job = new Job(lock);
            job.start();
        }
    }

    private static class Job extends Thread{

        private ReenTrantLock2 lock;

        public Job(ReenTrantLock2 lock){
            this.lock = lock;
        }

        @Override
        public void run() {
            lock.lock();
            System.out.println("当前线程:" + this.getName() + "等待线程:" + lock.getQueuedThreads().toString());
            lock.unlock();
            lock.lock();
            System.out.println("当前线程:" + this.getName() + "等待线程:" + lock.getQueuedThreads().toString());
            lock.unlock();
        }
    }
    private static class ReenTrantLock2 extends ReentrantLock{
        public ReenTrantLock2(Boolean flag){
            super(flag);
        }

        public Collection<Thread> getQueuedThreads(){
//            System.out.println(super.getQueuedThreads());
            List<Thread> list = new ArrayList<>(super.getQueuedThreads());
            return list;
        }
    }

}

原文地址:https://www.cnblogs.com/zhlblogs/p/10874793.html

时间: 2024-10-05 01:00:05

Lock的公平锁与非公平锁的相关文章

synchronized与lock 对象锁、互斥锁、共享锁以及公平锁和非公平锁

synchronized与lock  都是用来实现线程同步的锁,synchronized对象锁,lock是一个接口,她的实现有reentrantlock互斥锁以及ReentrantReadWriteLock共享锁. 这里说明一下ReentrantReadWriteLock共享锁,所谓共享就是该锁提供读读锁共享,即可以多个线程共享一个读取锁,但是读写锁以及读读锁是互斥的. 看到网上有好多介绍介绍锁的种类的,有对象锁.互斥锁.共享锁以及公平锁和非公平锁,但是说明都不够详细了然,在这里用直白的说法记录

java多线程20 : ReentrantLock中的方法 ,公平锁和非公平锁

公平锁与非公平锁 ReentrantLock有一个很大的特点,就是可以指定锁是公平锁还是非公平锁,公平锁表示线程获取锁的顺序是按照线程排队的顺序来分配的,而非公平锁就是一种获取锁的抢占机制,是随机获得锁的,先来的未必就一定能先得到锁,从这个角度讲,synchronized其实就是一种非公平锁.非公平锁的方式可能造成某些线程一直拿不到锁,自然是非公平的了.看一下例子,new ReentrantLock的时候有一个单一参数的构造函数表示构造的是一个公平锁还是非公平锁,传入true就可以了: publ

Java多线程编程4--Lock的使用--公平锁和非公平锁

公平与非公平锁:锁Lock分为"公平锁"和"非公平锁",公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,即先来先得的FIFO先进先出顺序.而非公平锁就是一种获取锁的抢占机制,是随机获得锁的,和公平锁不一样的就是先来的不一定先得到锁,这个方式可能造成某些线程一直拿不到锁,结果也就是不公平的了. 1.公平锁实例 public class Service { private ReentrantLock lock ; public Service(boolean i

公平锁与非公平锁源码对比

语义: 1.公平锁:每个线程在获取锁的时候,会先检查该锁维护的等待队列,如果该队列是空或者当前线程是第一个,则占有锁,否则按照FIFO的原则,进入等待队列,等待获取锁: 2.非公平锁:当前线程在获取锁的时候,不管该锁的维护队列种是否有其它等待线程,直接CAS,如果cas失败,则再执行公平锁的那一套: 源码比较如下:公平锁: final void lock() { acquire(1); } 非公平锁: final void lock() { if (compareAndSetState(0, 1

公平锁,非公平锁,乐观锁,悲观锁

公平锁/非公平锁(多线程执行顺序的维度) 概念理解 公平锁:加锁前先查看是否有排队等待的线程,有的话优先处理排在前面的线程,先来先得. 非公平所:线程加锁时直接尝试获取锁,获取不到就自动到队尾等待. 例子 ReentrantLock 同时支持两种锁 //创建一个非公平锁,默认是非公平锁 Lock nonFairLock= new ReentrantLock(); Lock nonFairLock= new ReentrantLock(false); //创建一个公平锁,构造传参true Lock

多线程学习 公平锁和非公平锁

公平与非公平锁:锁lock分为 公平锁和非公平锁,公平锁表示现场获取锁的顺序是按照线程加锁的顺序来分配的, 即先来先得的FIFO先进先出顺序.而非公平锁就是一种获取锁的抢占机制,是随机获得的锁的,和公平锁不一样的就是先来 不一定先得到锁,这个方式可能造成某些线程一直拿不到锁. 首先来验证公平锁:创建service方法,使用lock进行锁定. public class Service { private ReentrantLock lock; public Service(boolean isFa

Java中的公平锁和非公平锁实现详解

在ReentrantLock中包含了公平锁和非公平锁两种锁,通过查看源码可以看到这两种锁都是继承自Sync,而Sync又继承自AbstractQueuedSynchronizer,而AbstractQueuedSynchronizer又继承自AbstractOwnableSynchronizer,下面是类的继承关系图: 其中AbstractOwnableSynchronizer是提供了设置占用当前锁的线程信息的方法,主要的锁的实现还是在AbstractQueuedSynchronizer中实现的

理解ReentrantLock的公平锁和非公平锁

学习AQS的时候,了解到AQS依赖于内部的FIFO同步队列来完成同步状态的管理,当前线程获取同步状态失败时,同步器会将当前线程以及等待状态等信息构造成一个Node对象并将其加入到同步队列,同时会阻塞当前线程,当同步状态释放时,会把首节点中的线程唤醒,使其再次尝试获取同步状态. 这时,我有了一个疑问,AQS的同步队列是FIFO的,就是先来排队的先走.那怎么实现非公平锁呢?查阅了一些资料,总算知道了. 首先从公平锁开始看起. ReentrantLock 的公平锁 ReentrantLock 默认采用

带你快速了解Java锁中的公平锁与非公平锁

前言 Java语言中有许多原生线程安全的数据结构,比如ArrayBlockingQueue.CopyOnWriteArrayList.LinkedBlockingQueue,它们线程安全的实现方式并非通过synchronized关键字,而是通过java.util.concurrent.locks.ReentrantLock来实现. 锁的底层实现 无论什么语言在操作系统层面锁的操作都会变成系统调用(System Call),以 Linux 为例,就是 futex 函数,可以把它理解为两个函数:fu