129-如何实现一个自己的显式锁Lock精讲上

  1. 接口:
  2. BooleanLock实现类
  3. 测试调用方法
  4. 问题

synchronized的机制导致的一个问题:当线程A调用使用synchronized加锁的线程B时,如果线程B的运行时间很长,则调用者线程A将会进入阻塞状态,且不可打断,也不能立即返回。

接口:

/**
 * 自定义显式锁
 */
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();
}

BooleanLock实现类

public class BooleanLock implements Lock {
    /**
     * The initValue is true indicated the lock has been get.
     * The initValue is false indicated the lock is free (other thread can get this).
     */
    private boolean initValue;
    private Collection<Thread> blockedThreadCollection = new ArrayList<>();

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

    @Override
    public synchronized void lock() throws InterruptedException {
        // 锁已经被其他线程使用
        while (initValue) {
            blockedThreadCollection.add(Thread.currentThread());
            this.wait();
        }
        // 锁未被使用,抢到锁立即设置initValue的值
        this.initValue = true;
        blockedThreadCollection.remove(Thread.currentThread());
    }

    @Override
    public void lock(long mills) throws InterruptedException, TimeOutException {}

    @Override
    public synchronized void unlock() {
        // 释放锁
        this.initValue = false;
        Optional.of(Thread.currentThread().getName() + " release the lock monitor.").ifPresent(System.out::println);
        this.notifyAll();
    }

    @Override
    public Collection<Thread> getBlockedThread() {
        // 可以直接返回,但是不安全。此处返回的是一个实例,调用者可以随意更改(null,clear()等操作)。
        return Collections.unmodifiableCollection(blockedThreadCollection);
    }

    @Override
    public int getBlockedSize() {
        return blockedThreadCollection.size();
    }
}

测试调用方法

public static void main(String[] args) throws InterruptedException {
    final BooleanLock booleanLock = new BooleanLock();
    Stream.of("T1", "T2", "T3", "T4").forEach(name -> {
        new Thread(() -> {
            try {
                booleanLock.lock();
                Optional.of(Thread.currentThread().getName() + " have the lock Monitor.").ifPresent(System.out::println);
                work();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                booleanLock.unlock();
            }
        }, name).start();
    });

    // 问题:违规非法操作,导致运行混乱
    Thread.sleep(100);
    booleanLock.unlock();
}

private static void work() throws InterruptedException {
    Optional.of(Thread.currentThread().getName() + " is working...").ifPresent(System.out::println);
    Thread.sleep(10_000);
}

问题

违规非法操作,导致运行混乱。巨大的BUG

public static void main(String[] args) throws InterruptedException {
    final BooleanLock booleanLock = new BooleanLock();
    ...

    // 问题:违规非法操作,导致运行混乱
    Thread.sleep(100);
    booleanLock.unlock();
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 tuyrk@qq.com

文章标题:129-如何实现一个自己的显式锁Lock精讲上

文章字数:451

本文作者:神秘的小岛岛

发布时间:2019-12-01, 18:19:58

最后更新:2019-12-01, 22:21:49

原始链接:https://www.tuyrk.cn/wang-thread/129-custom-lock/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏