1.ReentrantLock与synchronized对比
相对于
synchronized
它具备如下特点
可中断
可以设置超时时间
可以设置为公平锁
支持多个条件变量
与
synchronized
一样,都支持可重入
基本语法:
lock.lock();
try {
}finally {
lock.unlock();
}
2.可重入
package com.xjq.ThreadDemo;
import sun.plugin.ClassLoaderInfo;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo {
private static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
lock.lock();
try {
System.out.println("mian 方法 lock");
m1();
}finally {
lock.unlock();
}
}
public static void m1(){
lock.lock();
try {
System.out.println("m1 方法locK");
m2();
}finally {
lock.unlock();
}
}
public static void m2(){
lock.lock();
try{
System.out.println("m2 方法lock");
}finally {
lock.unlock();
}
}
}
3.可中断
package com.xjq.ThreadDemo;
import java.util.concurrent.locks.ReentrantLock;
/**
* 可中断性
*/
public class ReentrantLockDemo01 {
private static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
try {
lock.lockInterruptibly(); //可打断lock
System.out.println("t1 进入lock。。。。。");
Thread.sleep(2000);
System.out.println("睡眠结束了。。。。");
} catch (InterruptedException e) {
System.out.println("t1线程被打断了");
//e.printStackTrace();
}finally {
lock.unlock(); //解锁
}
}, "t1");
Thread t2 = new Thread(() -> {
lock.lock();
try{
System.out.println("t2 进入lock。。。。");
t1.interrupt(); //打断t1线程
System.out.println("打断t1 进程");
}finally {
lock.unlock();
}
}, "t2");
t1.start();
t2.start();
}
}
执行结果:
t2 进入lock。。。。
打断t1 进程
t1线程被打断了
Exception in thread "t1" java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
at com.xjq.ThreadDemo.ReentrantLockDemo01.lambda$main$0(ReentrantLockDemo01.java:21)
at java.lang.Thread.run(Thread.java:748)
4.可设置超时时间
package com.xjq.ThreadDemo;
import java.sql.Time;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* 设置超时时间
* t1 占用锁,t2设置超时时间
*/
public class ReentrantLockDemo02 {
private static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
lock.lock();
try {
System.out.println("t1 获取到锁。。。。。");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}, "t1");
Thread t2 = new Thread(() -> {
try {
if (!lock.tryLock(2, TimeUnit.SECONDS)) { //tryLock()和tryLock(long,单位) 获取到锁返回值为true,否则返回为false
System.out.println("t2没有获取到锁");
return;
}
System.out.println("t2 获取到锁。。。。");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}, "t2");
t1.start();
t2.start();
}
}