JDK并发包--重入锁
Posted halazi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK并发包--重入锁相关的知识,希望对你有一定的参考价值。
重入锁基本使用:
使用java.util.concurrent.locks.ReentrantLock 类来实现,可以替代synchronized关键字。如下例,重入锁有着显示的操作过程,开发者可以手动指定在哪里加锁,在哪里释放(退出临界区时必须释放,不然其他线程没有机会再访问了)。重入的意思是,同一个线程可以多次获得锁,同样的退出时需要多次释放。
public class LockDemo implements Runnable{
public static ReentrantLock lock = new ReentrantLock();
public static int i=0;
public finnal int N= 10000;
@Override
public void run(){
for(int j=0;j<N;j++){
lock.lock(); //加锁
lock.lock();
try(
i++;
)finally{
lock.unlock(); //释放锁
lock.unlock();
}
}
}
public static void main(String[] args){
LockDemo tLock = new LockDemo();
Thread t1 = new Thread(tLock);
Thread t2 = new Thread(tLock);
t1.start();t2.start();
t1.join();t2.join();
System.out.println(i);//最终输出20000
}
}
中断响应:
对锁的请求使用lockInterruptibly()方法,可以在等待锁的过程中响应中断
package com.test;
import java.util.concurrent.locks.ReentrantLock;
public class IntruptLock implements Runnable{
public static ReentrantLock lock1 = new ReentrantLock();
public static ReentrantLock lock2 = new ReentrantLock();
int lock;//控制加锁顺序,方便构成死锁
public IntruptLock(int lock){this.lock = lock;}
public void run(){
try{
if(lock==1){
while(true){
lock1.lockInterruptibly();
try{
Thread.sleep(1000);
}catch(InterruptedException e) {
}
lock2.lockInterruptibly();
}
}else {
while(true){
lock2.lockInterruptibly();
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
lock1.lockInterruptibly();
}
}
}
}catch(InterruptedException e){
e.printStackTrace();
}finally{
if(lock1.isHeldByCurrentThread()) {
lock1.unlock();
}
if(lock2.isHeldByCurrentThread()) {
lock2.unlock();
}
System.out.println(Thread.currentThread().getName()+":线程退出");
}
}
public static void main(String[] args) throws InterruptedException {
IntruptLock r1 = new IntruptLock(1);
IntruptLock r2 = new IntruptLock(2);
//t1先获得lock1锁,再申请lock2,t2先获得lock2锁,再申请lock1,构成死锁
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
Thread.sleep(1000);
t2.interrupt();//中断t2,lock2响应中断,t2释放lock2锁,t1得以执行下去
}
}
tryLock():
仍然是上个栗子,如果使用的是tryLock(),t2在申请lock1时没有获得,它不会傻傻的等,而是会立刻返回false,然后继续执行重新尝试,只要时间够长,总会获得lock1而执行下去。
tryLock()也可以传入参数,tryLock(10,TimeUnit.SECONDS),分别表示时长和时间单位。
公平锁:
public ReentrantLock(boolean fair),各线程获得公平锁的概率是相等的。
以上是关于JDK并发包--重入锁的主要内容,如果未能解决你的问题,请参考以下文章
Java并发包4--可重入锁ReentrantLock的实现原理