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

  • 相关阅读:
    Python语法入门之基本数据类型
    ASCII,GBK,和Unicode的UTF-8,UTF-16,UTF-32阐述
    为什么计算机只认识0和1?
    Intel万兆网卡82599linux驱动安装
    Django自定义分页器
    Django图片防盗链
    Django配置用户上传文件夹和暴露后端文件夹资源
    Django之TruncMonth截取日期作为新的虚拟字段使用
    第十一篇:auth模块
    第十篇:跨站请求伪造csrf
  • 原文地址:https://www.cnblogs.com/moris5013/p/10716847.html
Copyright © 2011-2022 走看看