目录
2、ReentrantLock 和 Synchronized 的区别
1、ReentrantLock的常用方法有:
-
lock():获得锁,如果锁已被占用,则等待;
-
lockInterruptibly():获得锁,但优先响应中断;
-
tryLock():尝试获取锁,如果获取到则返回true,否则返回false,这种方式不会造成等待;
-
tryLock(long time, TimeUnit unit):在给定时间内获取锁,如果在给定时间内未获取到锁,则不再等待锁,执行其他任务;
-
unlock():释放锁;
2、ReentrantLock 和 Synchronized 的区别
(1) 中断响应
-
外部通知:如果一个线程正在等待锁,他可以收到一个中断通知,告诉其可以不用等待,而去执行其他任务。
-
内部设置等待时间:一个线程等待很长时间也没有获得锁的话,他可以选择放弃等待,去处理其他任务(使用tryLock(等待时间, 时间单位)来实现; 不带参数的tryLock()方法会尝试获取锁,如果获取到则返回true,否则返回false,这种方式不会造成等待)。
(2) 实现公平锁
一般锁都是非公平的(当某线程释放锁后,系统会从等待队列里随机取一个,可能会产生饥饿),ReentrantLock 可以按照先来先分配的方法实现公平锁,不会产生饥饿(使用有参构造函数即可设置公平锁)。
(3) 锁绑定多个条件(Condition对象)
Condition代替了synchronized的wait、notify、notifyall方法,condition和lock绑定,一个lock可以有多个condition,在不同的情况下使用不同的Condition。
例如,假如多线程读/写同一个缓冲区:当向缓冲区中写入数据之后,唤醒"读线程";当从缓冲区读出数据之后,唤醒"写线程";并且当缓冲区满的时候,"写线程"需要等待;当缓冲区为空时,"读线程"需要等待。
如果采用Object类中的wait(),notify(),notifyAll()实现该缓冲区,当向缓冲区写入数据之后需要唤醒"读线程"时,不可能通过notify()或notifyAll()明确的指定唤醒"读线程",而只能通过notifyAll唤醒所有线程(但是notifyAll无法区分唤醒的线程是读线程,还是写线程)。 但是,通过Condition,就能明确的指定唤醒读线程。