• Java 实现一个自己的显式锁Lock(有超时功能)


    Lock接口

    package concurency.chapter9;
    
    
    import java.util.Collection;
    
    public interface Lock {
        static class TimeOutException extends Exception {
            TimeOutException(String message) {
                super(message);
            }
        }
    
        void lock() throws InterruptedException;
    
        void lock(long mills) throws InterruptedException,TimeOutException;
    
        void unlock();
    
        Collection<Thread> getBlockedThread();
    
        int getBlockedSize();
    }
    

    Lock实现类

    package concurency.chapter9;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.Optional;
    
    public class BooleanLock implements Lock{
        public BooleanLock(boolean initValue) {
            this.initValue = initValue;
        }
    
        // false means is free
        // true means having been used
        private boolean initValue;
    
        private Thread currentThread;
    
        private Collection<Thread> blockedThreads = new ArrayList<>();
    
        @Override
        public synchronized void lock() throws InterruptedException {
            while(initValue) {
                blockedThreads.add(Thread.currentThread());
                this.wait();
            }
    
            blockedThreads.remove(Thread.currentThread());
            this.initValue = true;
            this.currentThread = Thread.currentThread();
        }
    
        @Override
        public synchronized void lock(long mills) throws InterruptedException, TimeOutException {
            // less than 0, Ignore it..
            if(mills <= 0)
                lock();
            long hasRemaining = mills;
            long endTime = System.currentTimeMillis() + mills;
            while(initValue) {
                if(hasRemaining <= 0)
                    throw new TimeOutException("time out, and the Thread[" + Thread.currentThread().getName()+"] do not get the lock");
                blockedThreads.add(Thread.currentThread());
                this.wait(mills);
                hasRemaining = endTime - System.currentTimeMillis();
            }
            blockedThreads.remove(Thread.currentThread());
            this.initValue = true;
            this.currentThread = Thread.currentThread();
        }
    
        @Override
        public synchronized void unlock() {
            if(currentThread != null && Thread.currentThread() == currentThread) {
                this.initValue = false;
                Optional.of(Thread.currentThread().getName() + " release the lock...").ifPresent(System.out::println);
                this.notifyAll();
            }
        }
    
        @Override
        public Collection<Thread> getBlockedThread() {
            return Collections.unmodifiableCollection(blockedThreads);
        }
    
        @Override
        public int getBlockedSize() {
            return blockedThreads.size();
        }
    }
    

    测试

    package concurency.chapter9;
    
    import java.util.Optional;
    import java.util.stream.Stream;
    
    public class LockTest {
        public static void main(String[] args) throws InterruptedException {
    
            final BooleanLock booleanLock = new BooleanLock(false);
            Stream.of("T1", "T2", "T3", "T4")
                    .forEach(name ->
                            new Thread(() -> {
                                try {
                                    booleanLock.lock(1000L);
                                    Optional.of(Thread.currentThread().getName() + " have the lock Monitor")
                                            .ifPresent(System.out::println);
                                    work();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                } catch (Lock.TimeOutException e) {
                                    System.out.println(e.getMessage());
    //                                Optional.of(Thread.currentThread().getName() + " time out")
    //                                        .ifPresent(System.out::println);
                                } finally {
                                    booleanLock.unlock();
                                }
                            }, name).start()
                    );
        }
    
        private static void work() throws InterruptedException {
            Optional.of(Thread.currentThread().getName() + " is Working...")
                    .ifPresent(System.out::println);
            Thread.sleep(10_000);
        }
    }
    

    测试结果

    T1 have the lock Monitor
    T1 is Working...
    time out, and the Thread[T2] do not get the lock
    time out, and the Thread[T3] do not get the lock
    time out, and the Thread[T4] do not get the lock
    T1 release the lock...
    
  • 相关阅读:
    CentOS7安装minio
    xshell连接虚拟机Connection failed
    Mysql时间加减函数
    mysql存储过程模板
    Activiti实现会签功能
    2018考研复试流程
    C编程经验总结5(剧终)
    《数据结构总结》
    《关于安卓和IOS开发》
    番外特别篇之 为什么我不建议你直接使用UIImage传值?--从一个诡异的相册九图连读崩溃bug谈起
  • 原文地址:https://www.cnblogs.com/Draymonder/p/10381412.html
Copyright © 2020-2023  润新知