Java并发编程——自定义Lock锁

一、引言

在学习JUC并发包的时,会介绍Lock锁。为了更深入的了解Lock锁的机制,我们可以自定义一个Lock锁,这样去读Lock源码可能好理解一点。

二、自定义Lock锁

1、定义Lock接口

public interface Lock {

	class TimeOutException extends Exception {
		public TimeOutException(String message) {
			super(message);
		}
	}

	void lock() throws InterruptedException;

	void lock(long mills) throws InterruptedException, TimeOutException;

	void unlock();

	Collection<Thread> getBlockedThread();

	int getBlockedSize();
}
2、Lock实现类
public class BooleanLock implements Lock {

	// 表示对象的锁是否被占用,true表示对象锁已经被占用
	private boolean initValue;

	// 表示被阻塞线程的集合
	private Collection<Thread> blockedThreadCollection = new ArrayList<>();

	// 记录获得当前对象锁的线程
	private Thread currentThread;

	public BooleanLock() {
		this.initValue = false;
	}

	/**
	 * 加锁,使用synchronized实现同步
	 */
	@Override
	public synchronized void lock() throws InterruptedException {
		// 如果锁已经被占用,则阻塞当前线程
		while (initValue) {
			//将线程加入到阻塞线程集合
			blockedThreadCollection.add(Thread.currentThread());
			this.wait();
		}

		// 锁没有被占用,则当前线程获得锁
		blockedThreadCollection.remove(Thread.currentThread());
		this.initValue = true;
		this.currentThread = Thread.currentThread();
	}

	/**
	 * 当线程等待一定时间后,没有释放锁,则其他线程抛出超时异常
	 */
	@Override
	public synchronized void lock(long mills) throws InterruptedException, TimeOutException {
		if (mills <= 0)
			lock();

		long hasRemaining = mills;
		long endTime = System.currentTimeMillis() + mills;
		while (initValue) {
			if (hasRemaining <= 0)
				throw new TimeOutException("Time out");
			blockedThreadCollection.add(Thread.currentThread());
			this.wait(mills);
			hasRemaining = endTime - System.currentTimeMillis();
		}

		this.initValue = true;
		this.currentThread = Thread.currentThread();
	}

	/**
	 * 释放锁
	 */
	@Override
	public synchronized void unlock() {
		// 只有占用锁对象的线程,才能释放锁。不然main线程释放锁,程序会有问题。
		if (Thread.currentThread() == currentThread) {
			this.initValue = false;
			System.out.println(Thread.currentThread().getName() + " release the lock monitor.");
			this.notifyAll();
		}
	}

	@Override
	public Collection<Thread> getBlockedThread() {
		//保证更新集合操作安全,不存在安全问题
		return Collections.unmodifiableCollection(blockedThreadCollection);
	}

	@Override
	public int getBlockedSize() {
		return blockedThreadCollection.size();
	}
}
3、测试
public class LockTest {

	public static void main(String[] args) throws InterruptedException {

		final BooleanLock booleanLock = new BooleanLock();

		//创建4个线程
		for (int i = 1; i < 5; i++) {

			new Thread("T" + i) {
				@Override
				public void run() {
					try {
						booleanLock.lock(10000);
						System.out.println(Thread.currentThread().getName() + " have the lock Monitor");
						work();
					} catch (InterruptedException e) {
						e.printStackTrace();
					} catch (Lock.TimeOutException e) {
						System.out.println(Thread.currentThread().getName() + " time out");
					} finally {
						booleanLock.unlock();
					}
				};
			}.start();
		}

	}

	private static void work() throws InterruptedException {
		System.out.println(Thread.currentThread().getName() + " is Working...");
		Thread.sleep(40_000);
	}
}
4、测试结果

在这里插入图片描述

三、小结

自定义一个Lock锁,熟悉Synchronized的同时,深入理解JUC中的Lock。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

止步前行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值