• 使用synchronized写一个显示锁


    public interface MyLock {
        
        void lock () throws InterruptedException;
        
        void lock(long millis) throws TimeoutException , InterruptedException ,ParametersIllegalException;
        
        void unlock();
        
        class TimeoutException  extends Exception{
            
            TimeoutException(String msg){
                super(msg);
            }
            private static final long serialVersionUID = 1L;
        }
        
        class ParametersIllegalException  extends Exception{
            
            ParametersIllegalException(String msg){
                super(msg);
            }
            private static final long serialVersionUID = 1L;
        }
    }
    public class MyLockImpl  implements MyLock{
    
        private boolean  initValue; // false表示monitor没有被占用
        
        private Thread currentThread;
        
        @Override
        public  synchronized void lock() throws InterruptedException {
            while(initValue) {//monitor被占用
                this.wait();
            }
            initValue = true;
            currentThread = Thread.currentThread();
        }
    
        @Override
        public synchronized void unlock() {
            if(currentThread == Thread.currentThread()) {
                System.out.println(""+Thread.currentThread().getName()+"" + " release the monitor");
                initValue = false;
                this.notifyAll();
            }
        }
    
        @Override
        public  synchronized void lock(long millis) throws TimeoutException, InterruptedException, ParametersIllegalException {
                if (millis <= 0) 
                   throw new ParametersIllegalException("parameters illegal");
                long hasRemaining = millis;
                long endTime = System.currentTimeMillis() + millis;
                while (initValue) {
                    if (hasRemaining <= 0)
                        throw new TimeoutException("Time out");
                    this.wait(millis);
                    hasRemaining = endTime - System.currentTimeMillis();
                }
                this.initValue = true;
                this.currentThread = Thread.currentThread();
        }
        
    
    }
    public class MyLockTest {
        
        public static void main(String[] args) {
            MyLock myLock = new MyLockImpl();
            
            Stream.of("T1","T2","T3","T4").forEach(name -> 
                new Thread(()-> {
                    try {
                        myLock.lock(10);
                        System.out.println(""+Thread.currentThread().getName()+"" +" get the monitor");
                        m1();
                    } catch (InterruptedException  e) {
                        e.printStackTrace();
                    } catch (TimeoutException e) {
                        System.out.println(""+Thread.currentThread().getName()+"" +" timeout");
                    } catch (ParametersIllegalException e) {
                        System.out.println(""+Thread.currentThread().getName()+"" +" parameter illegal");
                        //e.printStackTrace();
                    }finally {
                        myLock.unlock();
                    }
                },name).start()
            );
        }
        
        
        public static void m1() throws InterruptedException {
            System.out.println(""+Thread.currentThread().getName()+"" + "is working ...");
            Thread.sleep(3_000);
        }
    
    }

    注意wait方法可能存在spurious(假的)唤醒,wait方法应该在一个循环中使用

  • 相关阅读:
    delphi Base64
    delphi 注册表
    二、Spring Boot项目的三种启动方式
    Junit的运行流程以及Junit常用注解
    eclips集成单元测试
    六、AcriveMQ集群配置的三种方式,以及组合实现
    五、Sping 中实现简单实现activeMQ
    三、简单实现activeMQ发送消息
    二、安装ActiveMQ消息中间件
    一、消息中间件基础
  • 原文地址:https://www.cnblogs.com/moris5013/p/10716847.html
Copyright © 2020-2023  润新知