zoukankan      html  css  js  c++  java
  • 使用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方法应该在一个循环中使用

  • 相关阅读:
    人人都有数字替身的时代马上到来
    教你如何在linux下查看服务是否已经启动或者关闭
    提前了解2019年物联网发展的六大趋势
    本科理工男如何学习Linux
    linux常见命令ps的应用
    useradd 命令的常见用法
    简单聊聊Linux学习经历
    什么是公网IP、内网IP和NAT转换?
    远程获得的有趣的linux命令
    js练习题之查找数组中的位子
  • 原文地址:https://www.cnblogs.com/moris5013/p/10716847.html
Copyright © 2011-2022 走看看