您的位置:首页 > 编程语言 > Java开发

实战Java高并发程序设计之ReentrantLock(一)

2017-03-28 00:11 369 查看
重入锁的特性:

1.可重入.

public class ReentrantLockTest extends Thread {
public static ReentrantLock lock = new ReentrantLock();
public static int i = 0;
public void run(){
for(int j = 0;j<100000;j++){
lock.lock();
lock.lock();
try {
i++;
} finally{
lock.unlock();
lock.unlock();
}
}
}

public static void main(String[] args) throws Exception {
ReentrantLockTest lock = new ReentrantLockTest();
Thread t1 = new Thread(lock);
Thread t2 = new Thread(lock);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}


加几次锁释放几次.
与synchronized相比,重入锁需要开发人员手动指定何时加锁,何时释放锁

2.可中断

如果一个线程在等待锁,使用synchronized,那么结果只有两种,要么它获得锁继续执行,要么保持等待.

如果使用重入锁,就能提供另外一种可能,那就是线程可以被中断.
public class InLock implements Runnable{
public static ReentrantLock lock1 = new ReentrantLock();
public static ReentrantLock lock2 = new ReentrantLock();
int lock;
/**
* 控制加锁顺序,方便构造死锁
* @param lock
*/
public InLock(int lock){
this.lock = lock;
}
public void run() {
try {
if(lock == 1){
lock1.lockInterruptibly();		//是一个可以对中断进行相应的锁的申请
try {
Thread.sleep(500);
} catch (Exception e) {
}
lock2.lockInterruptibly();
}else{
lock2.lockInterruptibly();
try {
Thread.sleep(500);
} catch (Exception e) {
}
lock1.lockInterruptibly();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(lock1.isHeldByCurrentThread()){		//判断锁是否被当前线程占有
lock1.unlock();
}
if(lock2.isHeldByCurrentThread()){
lock2.unlock();
}
System.out.println(Thread.currentThread().getId()+":线程退出");
}
}
public static void main(String[] args) throws InterruptedException {
InLock r1 = new InLock(1);
InLock r2 = new InLock(2);
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
Thread.sleep(1000);
t2.interrupt();
}
}


3.可限时,tryLcok

超时不能获得锁,就返回false,不会永久等待构成死锁

public class ReentrantLockTest implements Runnable{
public static ReentrantLock lock = new ReentrantLock();

@Override
public void run() {
try {
//等待5s,等不到就退出
if(lock.tryLock(5,TimeUnit.SECONDS)){
Thread.sleep(6000);
}else {
System.out.println("get lock failed");
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
if(lock.isHeldByCurrentThread())	//不加会抛出异常
//最后记得释放锁
lock.unlock();
}
}
public static void main(String[] args) {
ReentrantLockTest t = new ReentrantLockTest();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
t2.start();
}
}


4.公平锁(先来先到)

公平锁需要维护一个有序队列,成本高,性能相对非常低下.因此默认锁是非公平的
public ReentrantLock(boolean fair);
public static ReentrantLock fairLock = new ReentrantLock(true);


下面来看看ReentrantLock源码:

public class ReentrantLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = 7373984872572414699L;
/** 提供所有实现机制的同步器 */
private final Sync sync;

/**
* 无参构造.默认是false
*/
public ReentrantLock() {
sync = new NonfairSync();
}

/**
* 有参构造
*/
public ReentrantLock(boolean fair) {
//true则创建公平锁,false非公平
sync = fair ? new FairSync() : new NonfairSync();
}
}


此处只讲基础使用,至于ReentrantLock的实现原理,后面将讲到

如有不足之处望指正.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐