reentrantlock可以用来代替synchronized
使用syn锁定的话如果遇到异常,jvm会自动释放锁,但是lock必须手动释放锁,因此经常在finally中进行锁的释放
class ReentrantLockDemo{
synchronized void m1(){
for (int i = 0; i < 10; i++) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
}
}
void m2(){
/**
* 在 try-finally 外加锁的话,如果因为发生异常导致加锁失败
* try-finally 块中的代码不会执行
* 相反,如果在 try{ } 代码块中加锁失败,finally 中的代码无论如何都会执行
* 但是由于当前线程加锁失败并没有持有 lock 对象锁,程序会抛出异常
*
* 详情参考 https://blog.csdn.net/u013568373/article/details/98480603
*/
lock.lock(); //相当于synchronized(this)
try {
for (int i = 0; i < 10; i++) {
TimeUnit.SECONDS.sleep(1);
System.out.println(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public static void main(String[] args) {
ReentrantLockDemo r1=new ReentrantLockDemo();
new Thread(r1::m1).start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(r1::m2).start();
}
}
reentrantlock可以进行“尝试锁定”trylock,这样无法锁定,或者在指定时间内无法锁定,线程可以决定是否继续
void m3(){
boolean locked=false;
try {
locked=lock.tryLock(5,TimeUnit.SECONDS);
System.out.println("m2...."+locked);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (locked) {
.....//业务逻辑
lock.unlock();
}
}
}
指定公平锁,谁等的时间长,线程就得到这把锁
public class ReentrantLock5 extends Thread {
private static ReentrantLock lock=new ReentrantLock(true);//参数为true表示为公平锁,可以对比输出结果
@Override
public void run() {
for (int i = 0; i < 100; i++) {
lock.lock();
try {
System.out.println(Thread.currentThread().getName()+"获得锁");
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
ReentrantLock5 r1=new ReentrantLock5();
Thread th1=new Thread(r1);
Thread th2=new Thread(r1);
th1.start();
th2.start();
}
}
还可以调用lockInterruptibly方法,可以对线程interrupt方法做出响应
public class ReentrantLock4 {
public static void main(String[] args) {
Lock lock=new ReentrantLock();
Thread t1=new Thread(()->{
lock.lock();
try {
System.out.println("t1 start");
TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
System.out.println("t1 end");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
});
t1.start();
Thread t2=new Thread(()->{
try {
lock.lockInterruptibly(); //可以对interrupt()做出响应
System.out.println("t2 start");
TimeUnit.SECONDS.sleep(5);
System.out.println("t2 end");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
});
t2.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.interrupt();//打断线程2的等待
}
}