您当前的位置: 首页 >  Java

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

发布时间:2019-03-30 23:56:30 ,浏览量:5

一、引言

在学习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。

关注
打赏
1688896170
查看更多评论

暂无认证

  • 5浏览

    0关注

    115984博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0568s