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方法应该在一个循环中使用

  • 相关阅读:
    Ubuntu1404: 将VIM打造为一个实用的PythonIDE
    事前备份胜于事后恢复
    做事不应当拘泥于既定的循例
    简单生活
    《犹太人思考术》读后感
    产品开发与运维的中心准则
    Awk使用一例:获取ASCII可见字符
    使用Sed和Awk实现批量文件的文本替换
    编写更少bug的程序的六条准则
    【JS新手教程】JS中的split()方法,拆分字符串
  • 原文地址:https://www.cnblogs.com/moris5013/p/10716847.html
Copyright © 2011-2022 走看看