相同点:
1.互斥锁
2.可重入(同一线程可重复获取同一把锁)
public class ReenTrantLockDemo {
private static final Lock lock = new ReentrantLock();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
int i = 0;
while (i < 10) {
++i;
try {
lock.lock();
System.out.println("跳出舒适圈第" + i + "天。。。。");
} finally {
lock.unlock();
}
}
} finally {
lock.unlock();
}
}
}).start();
}
}
不同点:
1. 级别不同:Synchronized是JVM层面,是Java语言关键字;ReentrantLock是API层面,需要显示的获取、释放锁
2. 响应中断:Synchronized不可响应中断,ReentrantLock可以响应中断
ReentrantLock独有的功能:
1. 公平锁:每个线程按照申请锁的顺序获取锁,Synchronized为非公平锁,而ReentrantLock默认是非公平锁,通过修改构造参数可以实现公平锁。
2. 响应中断:因为长时间等待或者线程进入死循环无法正常释放锁,ReentrantLock提供了lockInterruptibly()方法,线程可以中断等待,避免造成线程死锁。
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReenTrantLockDemo {
public static void main(String[] args) throws InterruptedException {
final Lock lock = new ReentrantLock();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
for (;;){
}
} finally {
lock.unlock();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lockInterruptibly();
System.out.println("获取中断锁。。。");
} catch (InterruptedException e) {
System.out.println("线程2被中断。。。");
e.printStackTrace();
} finally {
try {
lock.unlock();
} catch (Exception e){
}
}
}
});
t1.start();
t2.start();
t2.interrupt();
}
}
线程被中断后:
3. 限时等待:通过boolean tryLock(long timeout, TimeUnit unit)有参构造,如果指定时间内没有获取到锁,会自动返回false,反之返回true,避免长时间等待造成的死锁。
package com.sankuai.inf.leaf.server;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReenTrantLockDemo {
public static void main(String[] args) {
final Lock lock = new ReentrantLock();
new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
TimeUnit.SECONDS.sleep(5);
System.out.println("线程1结束。。。");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
boolean hasLock = false;
try {
if (hasLock = lock.tryLock(2, TimeUnit.SECONDS)) {
System.out.println("线程2获取锁成功。。。");
}else {
System.out.println("线程2获取锁失败。。。");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (hasLock) {
lock.unlock();
}
}
}
}).start();
}
}
未完待续。。。