最近正在阅读Java ReentrantLock源码,始终对可重入和不可重入概念理解不透彻,进行学习后记录在这里。...wait():阻塞当前线程 notify():唤起被wait()阻塞的线程 不可重入锁 所谓不可重入锁,即若当前线程执行某个方法已经获取了该锁,那么在方法中尝试再次获取锁时,就会获取不到被阻塞。...我们尝试设计一个不可重入锁: ? 使用该锁: ? 当前线程执行print()方法首先获取lock,接下来执行doAdd()方法就无法执行doAdd()中的逻辑,必须先释放锁。...这个例子很好的说明了不可重入锁。 可重入锁 接下来,我们设计一种可重入锁 ? 所谓可重入,意味着线程可以进入它已经拥有的锁的同步代码块儿。...可重入锁的概念和设计思想大体如此,Java中的可重入锁ReentrantLock设计思路也是这样
所谓重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的。 synchronized 和 ReentrantLock 都是可重入锁。...methodA1同步方法,如果其他线程没有获取A类的对象锁,那么当前线程就获得当前A类对象的锁,然后执行methodA1同步方法,方法体中调用methodA2同步方法,当前线程能够再次获取A类对象的锁,而其他线程是不可以的...代码演示: 不可重入锁: public class Lock{ private boolean isLocked = false; public synchronized void lock...这个例子很好的说明了不可重入锁。...摘自:JAVA可重入锁与不可重入锁 和 Java不可重入锁和可重入锁理解 发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/153277.html原文链接:https
这类函数我们称为不可重入函数。 ...如果这个函数不幸被设计成为不可重入的函数的话,那么不同任务调用这个函数时 可能修改其他任 务调用这个函数的数据,从而导致不可预料的后果。那么什么是可重入函数呢?...所谓可重入是指一个可以被多个任务调用的过程,任务在 调用时不必担心数据是否会 出错。不可重入函数在实时系统设计中被视为不安全函数。...把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写他。 其实很简单,只要遵守了几条很容易理解的规则,那么写出来的函数就是可重入的。 第一,不要使用全局变量。...把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写他。 其实很简单,只要遵守了几条很容易理解的规则,那么写出来的函数就是可重入的。 第一,不要使用全局变量。
不可重入锁示例(同一个线程不可以重入上锁后的代码段) 如下是一个不可重入锁的逻辑过程,会发现执行main方法控制台会打印执行doJob方法前,然后就会一直线程阻塞,不会打印执行doJob方法过程中,原因在于第一次上锁后...这种现象就造成了不可重入锁 public class Count{ MyLock lock = new MyLock(); public static void main(String...(同一个线程可以重入上锁的代码段,不同的线程则需要进行阻塞) java的可重入锁有:ReentrantLock(显式的可重入锁)、synchronized(隐式的可重入锁) 可重入锁诞生的目的就是防止上面不可重入锁的那种情况...,导致同一个线程不可重入上锁代码段。...设计可重入锁的示例代码 public class MyReentrantLock { boolean isLocked = false; // 默认没有上锁 Thread
最近正在阅读Java ReentrantLock源码,始终对可重入和不可重入概念理解不透彻,进行学习后记录在这里。...wait():阻塞当前线程 notify():唤起被wait()阻塞的线程 不可重入锁 所谓不可重入锁,即若当前线程执行某个方法已经获取了该锁,那么在方法中尝试再次获取锁时,就会获取不到被阻塞。...我们尝试设计一个不可重入锁: public class Lock{ private boolean isLocked = false; public synchronized void...这个例子很好的说明了不可重入锁。...可重入锁 接下来,我们设计一种可重入锁 public class Lock{ boolean isLocked = false; Thread lockedBy = null;
锁的简单应用 用lock来保证原子性(this.count++这段代码称为临界区) 什么是原子性,就是不可分,从头执行到尾,不能被其他线程同时执行。...(){ lock.lock(); this.count++; lock.unlock(); return count; } } 不可重入锁...} public synchronized void unlock(){ isLocked = false; notify(); } } 这其实是个不可重入锁...do something lock.unlock(); } } 当调用print()方法时,获得了锁,这时就无法再调用doAdd()方法,这时必须先释放锁才能调用,所以称这种锁为不可重入锁...这就是可重入锁的特点。
什么是可重入锁,什么是不可重入锁,它们是如何实现的?...定义 可重入锁:当线程获取某个锁后,还可以继续获取它,可以递归调用,而不会发生死锁; 不可重入锁:与可重入相反,获取锁后不能重复获取,否则会死锁(自己锁自己)。 不可重入锁 用代码说话。...基于 wait/notify 实现不可重入锁 import java.util.concurrent.locks.ReentrantLock; /** * 不可重入锁 */ public class...基于自旋锁实现不可重入锁 自旋锁,即获取锁的线程在锁被占用时,不是阻塞,而是不断循环去尝试,直到获取锁。...可重入锁 不可重入锁扩展一下,增加一个计数器,同一个线程每次获取锁计数器加1,释放锁减1,为0时释放锁。
什么是可重入函数 可重入函数指一个可同时被多个任务调用的过程,当一个函数满足下列条件时多为不可重入函数 (1)函数中使用了静态的数据结构; (2)函数中使用了malloc()、free()函数; (3...(如open、read、write、close等系统调用) 如何编写可重入函数 (1)编写可重入函数时,不应使用static局部变量,应使用auto即缺省态局部变量或寄存器变量。...不可重入函数示例: //Num为int型全局变量,函数Inc_Num返回Num加1的值 unsigned int example(int value) { unsigned int tmp;...Num = value; tmp = Inc_Num(); return tmp; } 可重入示例: //Num为int型全局变量,函数Inc_Num返回Num加1的值 unsigned
之前文章重点单独介绍过Synchronized和Reentrantlock,不明白的同学可以先看看了解: currentHashMap的公平锁,可中断响应,限制等待实例 这篇文章主要是介绍可重入锁和不可重入锁...,在jdk中synchronized和Reentrantlock,都是可重入锁,为了更高效的性能和防止发生死锁。...可重入锁可以理解为:同一个线程下,外层方法上锁之后,内层调用的方法也能正常获取锁。 下面先用代码介绍对【不可重入锁】的理解。...这就是不可重入锁。 可重入锁是什么呢?...我们自己可以用synchronized + wait + notify来实现不可重入锁,代码如下:
可重入锁InterProcessMutex 3. 不可重入锁InterProcessSemaphoreMutex 4. 可重入读写锁InterProcessReadWriteLock 5....可重入锁InterProcessMutex Reentrant和JDK的ReentrantLock类似, 意味着同一个客户端在拥有锁的同时,可以多次获取,不会被阻塞。...不可重入锁InterProcessSemaphoreMutex 具体实现:InterProcessSemaphoreMutex与InterProcessMutex调用方法类似,区别在于该锁是不可重入的,...在同一个线程中不可重入。...可重入读写锁InterProcessReadWriteLock 类似JDK的ReentrantReadWriteLock。一个拥有写锁的线程可重入读锁,但是读锁却不能进入写锁。
“不可重入”函数。...在使用不可重入函数时要注意:多条线程同时调用这些函数有可能会产生不一致的结果,产生这样结果的原因有三: 一是因为函数内部使用了共享资源,比如全局变量、环境变量。...二是因为函数内部调用了其他不可重入函数。 三是因为函数执行结果与某硬件设备相关。...从这点出发,如果你想要写一个线程安全的可重入函数的话,只要遵循以下原则就行了: A) 不使用任何静态数据,只使用局部变量或者堆内存。 B) 不调用上表中的任何非线程安全的不可重入函数。...如果不能同时满足以上两个条件,可以使用信号量、互斥锁等机制来确保使用静态数据或者调用不可重入函数时的互斥效果。这是编写多线程程序必须要注意的地方。
二、使用数据库悲观锁实现不可重入的分布式锁 这个比较简单,先来看代码: public class DBdistributedLock { private DataSource dataSource...三、总结 本文使用数据库悲观锁实现不可重入的分布式锁机制实现了一个分布式锁,大家想想如何使用乐观锁来实现那?到这里已经讲解了三种方式实现分布式锁,欢迎大家留言讨论,他们各自的优缺点,以及使用场景。
其实,如果不用锁上的条件 (newCondition()) ,也就不好体会重入。
文章前言 以太坊智能合约中的函数通过private、internal、public、external等修饰词来限定合约内函数的作用域(内部调用或外部调用),而我们将要介绍的重入漏洞就存在于合约之间的交互过程...案例分析 这里以Ethernaut闯关游戏中的一个重入案例为例作为演示说明: 闯关要求 盗取合约中的所有代币 合约代码 pragma solidity ^0.4.18; import 'openzeppelin-solidity...这样就能保证我们的fallback函数能被顺利执行,对应的,如果我们使用transfer和send函数来发送时,代码可用的gas仅有2300而已,这点gas可能仅仅只够捕获一个event,所以也将无法进行可重入攻击...防御措施 1、在可能的情况下,将ether发送给外部地址时使用solidity内置的transfer()函数,transfer()转账时只发送2300gas,不足以调用另一份合约(即重入发送合约),使用...] -= _amount;//生效 msg.sender.transfer(_amount);//交互 } } 3、使用互斥锁:添加一个在代码执行过程中锁定合约的状态变量,防止重入调用
使用Java进行多线程开发,使用锁是一个几乎不可避免的问题。今天,就让我们来聊一聊这个基础,但是又特别特别重要的话题。 首先,让我们来看一下,到底什么是锁? 以及,为什么要使用锁?...Java中的重入锁 Java中的锁都来自与Lock接口,如下图中红框内的,就是重入锁。 ?...重入锁的实现原理 重入锁内部实现的主要类如下图: ? 重入锁的核心功能委托给内部类Sync实现,并且根据是否是公平锁有FairSync和NonfairSync两种实现。这是一种典型的策略模式。...重入锁的使用示例 为了让大家更好的理解重入锁的使用方法。现在我们使用重入锁,实现一个简单的计数器。...默认情况下,重入锁是非公平的,公平的重入锁性能差于非公平锁 重入锁的内部实现是基于CAS操作的。
可重入锁详解 概述 什么是 “可重入”,可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。...例如 package com.test.reen; // 演示可重入锁是什么意思,可重入,就是可以重复获取相同的锁,synchronized和ReentrantLock都是可重入的 // 可重入降低了编程复杂性...package com.test.reen; import java.util.Random; import java.util.concurrent.locks.ReentrantLock; // 演示可重入锁是什么意思...} } finally { lock.unlock(); } } }).start(); } } 可以发现没发生死锁,可以多次获取相同的锁 可重入锁有
一、读取目录下的子文件: 1、在Linux系统下,打开和读取目录下的子文件主要是用opendir与readdir函数来操作的,我们解析一下这两个函数的原型: a、opendir函数: #include...如果有一个函数不幸被设计成为这样:那么不同任务调用这个函数时可能修改其他任务调用这个函数的数据,从而导致不可预料的后果。这样的函数是不安全的函数,也叫不可重入函数。...一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误;而不可重入的函数由于使用了一些系统资源,比如全局变量区...说明:若对所使用的全局变量不加以保护,则此函数就不具有可重入性,即当多个进程调用此函数时,很有可能使有关全局变量变为不可知状态。...这个设计方法是readdir不可重入的关键。readdir在多次调用时是有关联的,这个关联也标明readdir函数是不可重入的。
使用Java进行多线程开发,使用锁是一个几乎不可避免的问题。今天,就让我们来聊一聊这个基础,但是又特别特别重要的话题。 首先,让我们来看一下,到底什么是锁? 以及,为什么要使用锁?...如下图所示: 总结 可重入锁算是多线程的入门级别知识点,所以我把他当做多线程系列的第一章节,对于重入锁,我们需要特别知道几点: 对于同一个线程,重入锁允许你反复获得通一把锁...默认情况下,重入锁是非公平的,公平的重入锁性能差于非公平锁 重入锁的内部实现是基于CAS操作的。...重入锁的伴生对象Condition提供了await()和singal()的功能,可以用于线程间消息通信。
文章前言 以太坊智能合约中的函数通过private、internal、public、external等修饰词来限定合约内函数的作用域(内部调用或外部调用),而我们将要介绍的重入漏洞就存在于合约之间的交互过程...案例分析 这里以Ethernaut闯关游戏中的一个重入案例为例作为演示说明: 闯关要求 盗取合约中的所有代币 合约代码 pragma solidity ^0.4.18; import 'openzeppelin-solidity...这样就能保证我们的fallback函数能被顺利执行,对应的,如果我们使用transfer和send函数来发送时,代码可用的gas仅有2300而已,这点gas可能仅仅只够捕获一个event,所以也将无法进行可重入攻击...png 7.png 防御措施 1、在可能的情况下,将ether发送给外部地址时使用solidity内置的transfer()函数,transfer()转账时只发送2300gas,不足以调用另一份合约(即重入发送合约...] -= _amount;//生效 msg.sender.transfer(_amount);//交互 } } 3、使用互斥锁:添加一个在代码执行过程中锁定合约的状态变量,防止重入调用
存在漏洞的合约会不断向攻击者合约转账,终止循环结束(以太坊 gas 有上限) 常用转币方式 .reansfer() 发送失败时会通过 throw 回滚状态,只会传递 2300 个 gas 以供调用,从而防止重入....send() 发送失败时,返回布尔值 false,只会传递 2300 个 gas 以供调用,从而防止重入 .gas().call.value()() 当发送失败时...,返回布尔值 false 将传递所有可用的 gas 进行调用(可通过 gas(gas _value) 进行限制),不能有效防止重入攻击 代码调试 pragma solidity ^0.4.19; contract...reentry 函数,进行攻击,然后看一下余额,发现原本在 victim 中的以太币全都到了 Attacker 合约中,同时 test 的值为 11,说明 fallback 函数被调用了 11 次 漏洞防范 重入漏洞的关键在于...虽然代码中存在判断语句,但是状态更新在函数调用之后,所以状态更新会因为循环调用而迟迟无法执行 广义上看,重入攻击条件有以下两个: 调用合约外部函数。
领取专属 10元无门槛券
手把手带您无忧上云