java 手动实现一个可重入锁

手动实现一个可重入锁

下面代码给出了一个手动实现的可重入锁,MyLock类,实现了Lock接口,需要编写的两个函数为lock()和unlock()。isLocked变量用来判断当前是否有线程使用,若没有,则为false。lockBy变量保存了当前持有的线程。lockcount变量保存当前持有的线程的计数器。函数中调用wait()和notify()时,需要加上关键字synchronized。

package com.concur.class21;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class MyLock implements Lock{
    
	private boolean isLocked=false;
	private Thread lockBy=null;
	private int lockcount=0;
	@Override
	public synchronized void lock() {
		Thread currentThread=Thread.currentThread();//1
		while(isLocked&&currentThread!=lockBy)){//2
			try {
				wait();//3
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		isLocked=true;//4
		lockBy=currentThread;//5
		lockcount++;//6
	}
	@Override
	public synchronized void unlock() {
		if(lockBy==Thread.currentThread()){//7
			lockcount--;//8
			if(lockcount==0){//9
				notify();//10
				isLocked=false;//11
			}
		}
		
	}


	@Override
	public void lockInterruptibly() throws InterruptedException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean tryLock() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Condition newCondition() {
		// TODO Auto-generated method stub
		return null;
	}

}

下面结合实例来分析上面手动实现的可重入锁,首先设计了一个Test类,定义了两个函数a()和b(),在函数a()中加锁并调用b()函数,在b()函数中,同样进行加锁操作。

当只有一个线程时:

  1. 进入函数a(),首先调用lock.lock()函数,执行步骤1,此时currentThread=thread0,执行步骤2,isLocked=false,currentThread=thread0,lockBy=null,并不进入while循环,则执行步骤4-6,isLocked=true,lockBy=thread0,lockcount=1
  2. 进入函数b(),同样调用lock()函数,执行步骤1,此时currentThread=thread0,执行步骤2,isLocked=true,currentThread=lockBy,不满足条件,并不进入while循环,则执行步骤4-6,isLocked=true,lockBy=thread0,lockcount=2
  3. 调用函数b()中的unlock()函数,执行步骤7,lockBy=thread0=Thread.currentThread,则执行步骤8,lockcount=1,退出函数
  4. 接着调用函数a()中的unlock()函数,执行步骤7,同样满足判断,lockcount=0,执行步骤10-11,调用notify()函数通知其他线程,并设置isLocked变量为false。

当有多个线程竞争时:

通过比较currentThread变量(当前想要获取锁的线程)和lockBy(当前已经持有锁的线程)进行比较,如果不相同,则调用wait()函数,直到有线程调用notify()通知。

package com.concur.class21;

import java.util.concurrent.locks.Lock;

public class Test {
	Lock lock=new MyLock();
	public void a(){
		lock.lock();
		System.out.println("a");
		b();
		lock.unlock();
	}
	public void b(){
		lock.lock();
		System.out.println("b");
		lock.unlock();
	}
	public static void main(String[] args) {
		Test test=new Test();
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				test.a();				
			}
		}).start();
	}

}

输出结果:

a
b

    原文作者:java锁
    原文地址: https://blog.csdn.net/u010512429/article/details/79971811
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞