可重入锁ReentrantLock

参考:https://blog.csdn.net/qq_38293564/article/details/80515718

https://segmentfault.com/a/1190000014419022?utm_source=index-hottest

1.ReentrantLock分为公平锁和非公平锁,默认是不公平锁。(为什么默认是不公平锁呢?因为不公平锁线程切换少,吞吐率会更高,但是不公平锁容易造成“饥饿”)

公平锁就和syncnized差不多,先到先得,

非公平锁,就是ReentrantLock可重入的意思。就是当你当前的线程,或者你当前线程的子线程可以优先于其他的排队的线程获取到锁。

举个例子,有一个房间,房间里面有一个宝箱,拥有ReentrantLock的人可以打开宝箱。公平锁就是,只要你放下了ReentrantLock,就算你还没有出房子,你想再拿起ReentrantLock的时候去开宝箱的时候,也必须要出去拍到队尾去等着。非公平锁就是,只要你还没出房子,你就可以再拿起ReentrantLock去再开宝箱。这个例子里面房间等于线程,开宝箱是你线程里要做的事,拥有ReentrantLock和放下ReentrantLock就是lock()和unlock().

根据我参考的那个文章,自己差不多的写了的例子

package com.xq.demo.reentrantLock;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.ReentrantLock;

public class MyFairAndUnfairTest {

    private static class MyReentrantLock extends ReentrantLock {
        public MyReentrantLock(boolean fair) {
            super(fair);
        }

        public Collection<Thread> getQueuedThreads() {
            List<Thread> arrayList = new ArrayList<Thread>(super.getQueuedThreads());
            Collections.reverse(arrayList);
            return arrayList;
        }
    }
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(10);
        //MyReentrantLock myReentrantLock = new MyReentrantLock(true);
        MyReentrantLock myReentrantLock = new MyReentrantLock(false);
        for(int i=0;i<10;i++){
            Worder worder = new Worder(myReentrantLock,cyclicBarrier);
            worder.setName(i+"");
            worder.start();
        }
    }

    static class Worder extends Thread{
        private MyReentrantLock myReentrantLock;
        private CyclicBarrier cyclicBarrier;

        public Worder(MyReentrantLock myReentrantLock,CyclicBarrier cyclicBarrier){
            this.myReentrantLock=myReentrantLock;
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run(){
            System.out.println(getName()+"准备好了");
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            for(int i=0;i<2;i++){
                myReentrantLock.lock();
                System.out.println("当前占有锁的线程是:"+getName()+",等待获取锁的队列:"+myReentrantLock.getQueuedThreads());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                myReentrantLock.unlock();
            }

        }
        public String toString() {
            return getName();
        }
    }
}


我们来分析代码运行的结果

首先是

MyReentrantLock myReentrantLock = new MyReentrantLock(false); 非公平锁,以下图片可以观察到,当线程9获取到锁,又释放锁,线程还没结束for循环再次获取锁的时候9又先于其他的等待线程着获取到了锁。

MyReentrantLock myReentrantLock = new MyReentrantLock(true);公平锁,下图结果可以看出,当线程9获取到锁,又释放锁,线程还没结束for循环再次获取锁的时候9被排到了等待锁的队尾去了。然后直到它前面排队的都走完,才轮到它。其他线程也一样。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值