ReentrantLock学习

1、ReentrantLock介绍

ReentrantLock是一种可重入的共享或排它锁
ReentrantLock内部使用CAS实现,不会像Synchronized引起上下文切换和线程调度
ReentrantLock提供比Synchronized更多的功能

ReentrantReadWriteLock与ReentrantLock没有继承关系,实现是相互独立的

2、ReentrantLock排它锁

代码示例

public class TestTest
{
    public static void main(String[] args) throws ParseException
    {
        ReentrantLock reenTrantLock = new ReentrantLock();
        int THREAD_NUM = 3;
        ExecutorService executorService = Executors.newFixedThreadPool(THREAD_NUM);
        for(int i=0;i<THREAD_NUM;i++){
            executorService.execute(new TestThread(reenTrantLock));
        }
        executorService.shutdown();
        while(!executorService.isTerminated()){
            ;
        }
        System.out.println("----end----");
    }  
}

class TestThread implements Runnable {

    private ReentrantLock innerLock;
    public TestThread(ReentrantLock innerLock){
        this.innerLock = innerLock;
    }

    @Override
    public void run()
    {
        innerLock.lock();
        try {
            for(int i=1;i<=3;i++){
                System.out.println(Thread.currentThread() + " lock " + i);
            }
        } finally {
            innerLock.unlock();
        }
    }
}

输出结果
说明:不会出现交叉输出的情形,例如 1 1 2 3 2 3 …..,说明线程安全

Thread[pool-1-thread-1,5,main] lock 1
Thread[pool-1-thread-1,5,main] lock 2
Thread[pool-1-thread-1,5,main] lock 3
Thread[pool-1-thread-2,5,main] lock 1
Thread[pool-1-thread-2,5,main] lock 2
Thread[pool-1-thread-2,5,main] lock 3
Thread[pool-1-thread-3,5,main] lock 1
Thread[pool-1-thread-3,5,main] lock 2
Thread[pool-1-thread-3,5,main] lock 3

3、ReentrantLock非公平锁与公平锁

默认是非公平锁:ReentrantLock reenTrantLock = new ReentrantLock(boolean isFair);
非公平锁VS公平锁:1)实际情况下,线程需要连续多次获取锁才能完成逻辑处理;2)非公平锁使得当前线程连续获取锁,而不是按照请求时间先后排队,最终能得到较高的TPS;3)非公平锁容易导致【线程饥饿】,即排队时间长的线程反而获取不到锁

【非公平锁】代码测试

 @Override
    public void run()
    {
        for(int i=1;i<=3;i++){
            innerLock.lock();   // 在同一个线程内,连续多次获取锁
            try {
                System.out.println(Thread.currentThread() + " lock " + i);
            } finally {
                innerLock.unlock();
            }
        }
    }

【非公平锁】测试输出结果
说明:同一个线程内的输出基本是连续的,说明线程内多次尝试获取锁成功概率很高

Thread[pool-1-thread-1,5,main] lock 1
Thread[pool-1-thread-2,5,main] lock 1
Thread[pool-1-thread-2,5,main] lock 2
Thread[pool-1-thread-2,5,main] lock 3
Thread[pool-1-thread-1,5,main] lock 2
Thread[pool-1-thread-1,5,main] lock 3
Thread[pool-1-thread-3,5,main] lock 1
Thread[pool-1-thread-3,5,main] lock 2
Thread[pool-1-thread-3,5,main] lock 3
----end----

【公平锁】代码测试:ReentrantLock reenTrantLock = new ReentrantLock(true);
【公平锁】测试结果:增加线程数后输出结果更明显,排队靠前的线程优先获取锁

Thread[pool-1-thread-1,5,main] lock 1
Thread[pool-1-thread-3,5,main] lock 1
Thread[pool-1-thread-5,5,main] lock 1
Thread[pool-1-thread-2,5,main] lock 2
Thread[pool-1-thread-4,5,main] lock 2
Thread[pool-1-thread-1,5,main] lock 2
Thread[pool-1-thread-3,5,main] lock 2
Thread[pool-1-thread-5,5,main] lock 2
Thread[pool-1-thread-2,5,main] lock 3
Thread[pool-1-thread-4,5,main] lock 3
Thread[pool-1-thread-1,5,main] lock 3
Thread[pool-1-thread-3,5,main] lock 3
Thread[pool-1-thread-5,5,main] lock 3
Thread[pool-1-thread-2,5,main] lock 4
Thread[pool-1-thread-4,5,main] lock 4
Thread[pool-1-thread-1,5,main] lock 4
Thread[pool-1-thread-3,5,main] lock 4
Thread[pool-1-thread-5,5,main] lock 4
Thread[pool-1-thread-2,5,main] lock 5
Thread[pool-1-thread-4,5,main] lock 5
Thread[pool-1-thread-1,5,main] lock 5
Thread[pool-1-thread-3,5,main] lock 5
Thread[pool-1-thread-5,5,main] lock 5
----end----

4、ReentrantReadWriteLock

允许多个线程同时获取读锁
不允许多个线程同时获取写锁
当前有读锁没有被释放,则写锁获取被阻塞
当前有写锁没有被释放或有写锁等待,则读锁获取被阻塞

代码测试

public class ReadWriteLockTest {

    public static void main(String[] args){
        ReadWriteLock rwLock = new ReentrantReadWriteLock();
        final WorkTest workTest = new WorkTest(rwLock);
        int threadNum = 3;
        for(int i=0;i<threadNum;i++){
            new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    while(true){
                       workTest.get();
                    }
                }
            },"Thread-"+i).start();
        }

        for(int j=threadNum;j<threadNum*2;j++){
            new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    while(true){
                        workTest.set();
                    }
                }
            },"Thread-"+j).start();
        }
    }
 }

class WorkTest{

    private String sharedStr; // 共享的对象
    private ReadWriteLock rwLock; 
    private Random random = new Random();

    public WorkTest(ReadWriteLock rwLock){
        this.rwLock = rwLock;
    }

    public void get(){
        rwLock.readLock().lock(); // 获取读锁
        System.out.println(Thread.currentThread().getName() + " get readLock");

        try {
            try
            {
                Thread.sleep(random.nextInt(1000));
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "  read completed: " + sharedStr);
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public void set(){
        rwLock.writeLock().lock();  // 获取写锁
        System.out.println(Thread.currentThread().getName() +  " got  writeLock ");

        try {
            try
            {
                Thread.sleep(random.nextInt(1000));
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            sharedStr = Integer.toString(random.nextInt(1000));
            System.out.println(Thread.currentThread().getName() +  " write completed: " + sharedStr);
        } finally {
            rwLock.writeLock().unlock();
        }
    }
}

输出结果

Thread-1 get readLock       // 两个线程同时持有读锁
Thread-0 get readLock       // 两个线程同时持有读锁
Thread-1  read completed: null
Thread-0  read completed: null
Thread-3 got  writeLock 
Thread-3 write completed: 895
Thread-5 got  writeLock 
Thread-5 write completed: 64
Thread-4 got  writeLock 
Thread-4 write completed: 870
Thread-4 got  writeLock 
Thread-4 write completed: 900
Thread-2 get readLock
Thread-1 get readLock
Thread-0 get readLock
Thread-1  read completed: 900
Thread-0  read completed: 900
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值