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 <= )
throw new ParametersIllegalException("parameters illegal");
long hasRemaining = millis;
long endTime = System.currentTimeMillis() + millis;
while (initValue) {
if (hasRemaining <= )
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();
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方法应该在一个循环中使用

采用synchronized关键字写一个显示锁的更多相关文章

  1. 使用semaphore写一个显示锁

    /** * 这里只是将Semaphore包装了一下,注意当Semaphore的构造参数是1时,本身就是一个显示锁 */ public class SemaphoreLock { ); public v ...

  2. 使用AtomicInteger写一个显示锁

    利用了AtomicInteger的compareAndSet方法 public class CASLock { private AtomicInteger value = new AtomicInte ...

  3. 如何使用Shell写一个显示目录结构的命令?

    公众号关注 「开源Linux」 回复「学习」,有我为您特别筛选的学习资料~ 在Linux中使用Shell写一个显示目录结构的命令,快速寻找目录结构. 1.代码 #!/usr/bin/env bash ...

  4. Java:synchronized关键字引出的多种锁

    前言 Java 中的 synchronized关键字可以在多线程环境下用来作为线程安全的同步锁.本文不讨论 synchronized 的具体使用,而是研究下synchronized底层的锁机制,以及这 ...

  5. 用javascript写一个显示时间差 几分钟前 几小时前 几天前 几周前 大于一个月显示日期

    window.onload = function(){ var show_times = $(".times span"); for(var i=0;i<show_times ...

  6. JAVA多线程之Synchronized关键字--对象锁的特点

    一,介绍 本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点. 所谓对象锁,就是就是synchronized 给某个对象 加锁.关于 对象锁 可参考:这篇文章 二,分析 s ...

  7. java线程总结--synchronized关键字,原理以及相关的锁

    在多线程编程中,synchronized关键字非常常见,当我们需要进行“同步”操作时,我们很多时候需要该该关键字对代码块或者方法进行锁定.被synchronized锁定的代码块,只能同时有一条线程访问 ...

  8. 精通java并发-synchronized关键字和锁

    目前CSDN,博客园,简书同步发表中,更多精彩欢迎访问我的gitee pages synchronized关键字和锁 示例代码 public class MyThreadTest2 { public ...

  9. Java多线程:synchronized关键字和Lock

    一.synchronized synchronized关键字可以用于声明方法,也可以用来声明代码块,下面分别看一下具体的场景(摘抄自<大型网站系统与Java中间件实践>) 案例一:其中fo ...

随机推荐

  1. plsql中的procedure和function编程

    procedure:存储过程 eg:   create or replace procedure p   --这儿是和plsql的区别         is         cursor c      ...

  2. leetcode — palindrome-partitioning-ii

    import java.util.Arrays; /** * * Source : https://oj.leetcode.com/problems/palindrome-partitioning-i ...

  3. 在centos7中python3的安装注意

    ---恢复内容开始--- 云主机的python是2.7有些不方便,故要更换3,看到官网有3.6的包,就下载了. wget https://www.python.org/ftp/python/3.6.3 ...

  4. Nlog、Log4Net 的一个小扩展(增加自定义LEVEL)

    因公司ELK监控分析日志的需要,需要区分进程运行状态日志以及错误日志,以便能够根据日志级别(level)进行不同策略的预警,而现有的Nlog.Log4Net都没有Process这样的level,故针对 ...

  5. Nacos系列:基于Nacos的注册中心

    前言 所谓注册中心,其实是分布式架构演进过程中的产物,在系统中充当一个协调者的角色.但是,为什么需要这样一个协调者的角色呢?我们先来看一个例子,以便理解为什么分布式架构中需要有注册中心. 案例 小明和 ...

  6. 从零开始学安全(三十八)●cobaltstrike生成木马抓肉鸡

    链接:https://pan.baidu.com/s/1qstCSM9nO95tFGBsnYFYZw 提取码:w6ih  上面是工具 需要java jdk 在1.8.5 以上  实验环境windows ...

  7. C#把动态创建的多个控件中指定控件显示在最上层

    在创建多个控件后,有些控件会发生重叠,那么就需要在鼠标按下它时能显示在最上层,下面通过先将按下操作的控件删除然后再重建,就达到让它显示在最上层了 //控件按下 private void picture ...

  8. ElasticSearch6学习(1)-安装Elasticsearch

    安装准备: 安装Elasticsearch唯一的要求是安装Java8,包括对应的Jdk.其他java9/java10没尝试,考虑兼容问题.我这里只用了java8 安装java8可以参考我之前写的一篇文 ...

  9. 配置多个git账号的ssh密钥

    博客改版,请直接访问新版文章:https://www.cnblogs.com/xiaoxi666/p/9975981.html 背景 我们在工作中会以 ssh 的方式配置公司的 git 账号,但是平时 ...

  10. Python爬取地图瓦片

    由于要在内网开发地图项目,不能访问在线的地图服务了,就想把地图瓦片下载下来,网上找了一些下载器都是需要注册及收费的,否则下载到的图都是打水印的,如下: 因为地图瓦片就是按照层级.行.列规则组织的一张张 ...