大多数情况下,大家可能都会选择使用synchronized来加锁,ReentrantLock确实是一种高级加锁工具,在确实需要一些 synchronized 所没有的特性的时候,比如时间锁等候、可中断锁等候、无块结构锁、多个条件变量或者锁投票。
以下实现公平锁和非公平锁,公平锁在性能上会多消耗点
package com.cmcc.web.test.lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockTest {
private static final ReentrantLock lock = new ReentrantLock();
private static final ReentrantLock fairlock = new ReentrantLock(true);
private int n;
public static void main(String[] args) {
ReentrantLockTest rlt = new ReentrantLockTest();
for (int i = 0; i < 100; i++) {
Thread nonT = new Thread(new NonFairTestThread(rlt));
nonT.setName("nonFair[" + (i + 1) + "]");
nonT.start();
Thread fairT = new Thread(new FairTestThread(rlt));
fairT.setName("fair[" + (i + 1) + "]");
fairT.start();
}
}
// 非公平锁
static class NonFairTestThread implements Runnable {
private ReentrantLockTest rlt;
public NonFairTestThread(ReentrantLockTest rlt) {
this.rlt = rlt;
}
public void run() {
lock.lock();
try {
rlt.setNum(rlt.getNum() + 1);
System.out.println(Thread.currentThread().getName()
+ " nonfairlock***************" + rlt.getNum());
} finally {
lock.unlock();
}
}
}
// 公平锁
static class FairTestThread implements Runnable {
private ReentrantLockTest rlt;
public FairTestThread(ReentrantLockTest rlt) {
this.rlt = rlt;
}
public void run() {
fairlock.lock();
try {
rlt.setNum(rlt.getNum() + 1);
System.out.println(Thread.currentThread().getName()
+ " fairlock=======" + rlt.getNum() + " "
+ fairlock.getHoldCount() + " queuelength="
+ fairlock.getQueueLength());
} finally {
fairlock.unlock();
}
}
}
public void setNum(int n) {
this.n = n;
}
public int getNum() {
return n;
}
}
package com.cmcc.web.test.lock;
import java.util.concurrent.locks.ReentrantLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestLock {
private final static Logger logger = LoggerFactory.getLogger(TestLock.class);
private static final ReentrantLock lock = new ReentrantLock(true);
private static final ReentrantLock lock1 = new ReentrantLock(true);
// 设置一个锁,然后休眠,另外一个线程获取这个锁的时候如果这个锁有人在使用的就不跳过了
public static void main(String[] args) throws InterruptedException {
Test1 test1 = new Test1();
test1.start();
Thread.sleep(500);
Test2 test2 = new Test2();
test2.start();
}
static class Test1 extends Thread {
public void run() {
lock.lock();
lock1.lock();
for (int i=0;i<2;i++) {
logger.info("lock1被我锁住了");
if (i==0) {
lock.unlock();
}
if (i==1) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock1.unlock();
}
}
// lock.lock();
// try {
// logger.info(this.hashCode() + this.hashCode() + "开始休眠");
// //Thread.sleep(5000);
// logger.info(this.hashCode() + "开始结束");
// }catch (Exception e) {
//
// }
// finally {
// lock.unlock();
// }
}
}
static class Test2 extends Thread {
public void run() {
//如果锁可用,则获取锁,并立即返回值 true。
//如果锁不可用,则此方法将立即返回值 false。
boolean lockBoolean = lock1.tryLock();
if (lockBoolean) {
logger.info(this.hashCode() + "当前锁1可以使用");
} else {
logger.info(this.hashCode() + "当前锁1不可以使用");
}
logger.info(this.hashCode() + "那我就等着吧");
lock.lock();
try {
logger.info(this.hashCode() + "我得到锁了");
}catch (Exception e) {
}
finally {
lock.unlock();
}
lock1.lock();
try {
logger.info(this.hashCode() + "我得到锁了1");
}catch (Exception e) {
}
finally {
lock1.unlock();
}
}
}
}