/****
* 通过重写Lock接口来实现ReentrantLock来理解ReentrantLock原理
*/
public class JamesReentrantLock implements Lock {
//标记重入次数的count值
AtomicInteger count=new AtomicInteger(0);
//锁的持有者
AtomicReference<Thread>owner=new AtomicReference<>();
//等待队列
private LinkedBlockingQueue<Thread> waiters=new LinkedBlockingQueue<>();
@Override
public boolean tryLock() {
//判断count是否为0,若count!=0,说明锁被占用
int ct=count.get();
if(ct!=0){
//判断锁是否被当前线程占用,若被当前线程占用,做重入操作,count+=1
if(owner.get()==Thread.currentThread()){
count.set(ct+1);
return true;
}else {
//若不是当前当前线程占用,互斥,抢锁失败。return false;
return false;
}
}else {//若count=0.说明锁未被占用,通过CAS(0,1)来抢锁
if(count.compareAndSet(ct,ct+1)){
//若抢锁成功,设置owner为当前线程的引用
owner.set(Thread.currentThread());
return true;
}else {
return false;
}
}
}
@Override
public void lock() {
//尝试抢锁,tryLock()成功的话,则直接抢到了锁;tryLock()失败进行如下操作
if(!tryLock()){
//如果抢锁失败,进入等待队列
waiters.offer(Thread.currentThread());
//自旋
for (;;){
//判断是否是队列头部,如果是再次发起抢锁;头部有两种情况,一是队列此时为空直接再次抢锁,二是队列被唤醒,如果处 于队列头则再次进入抢锁,应该属于公平锁
Thread head=waiters.peek();
if(head==Thread.currentThread()){
//再次尝试抢锁
if(!tryLock()){
//若抢锁失败,挂起线程,继续等待
LockSupport.park();
}else {
//若成功,就出队列
waiters.poll();
return;//退出自旋
}
}else{
//如果不是waiters队首,就挂起线程
LockSupport.park();
}
}
}
}
@Override
public void unlock() {
if(tryUnlock()){
Thread th=waiters.peek();
if(th!=null){
LockSupport.unpark(th);
}
}
}
public boolean tryUnlock(){
//判断,是否是当前当前线程占有锁,若不是抛异常
if(owner.get()!=Thread.currentThread()){
throw new IllegalMonitorStateException();
}else {
//如果是,就将count-1 若count变为0,则解锁成功,(因为当前操作是获取到锁才执行的,所以以下几个操作不会被分割)
int ct=count.get();
int next=ct-1;
count.set(next);
//判断count值是否为0
if(next==0){
owner.compareAndSet(Thread.currentThread(),null);
return true;
}else {
return false;
}
}
}
}
static JamesReentrantLock lc = new JamesReentrantLock();
private static int num = 0;
public static void main(String args[]) throws InterruptedException {
/* for (int i=0; i<10; i++){
new Thread(){
@Override
public void run() {
for (int j=0; j< 10000; j++){
//System.out.println(currentThread().getName()+ "....");
add();
}
System.out.println("done...");
}
}.start();
}
Thread.sleep(6000L);
System.out.println(i);
}*/
int count = 2000;
CountDownLatch countDownLatch = new CountDownLatch(count);
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
lc.lock();
Thread thread = Thread.currentThread();
System.out.println("--start--"+thread.getName());
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
num++;
System.out.println("--end--");
countDownLatch.countDown();
}finally {
lc.unlock();
}
}
};
Thread thread = null;
for (int i = 0; i < count; i++) {
thread = new Thread(runnable,"t"+i);
thread.start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("--num--"+num);
}
在这里插入代码片