import java.util.concurrent.locks.ReentrantLock;

/**
* 重入锁 ReenterLock 一个线程允许连续获得同一把锁,注意:必须释放相同次数,释放次数多,会异常,少了相当于线程还持有这个锁,其他线程无法进入临界区
* 需要手动指定何时加锁何时释放锁
*
ReenterLock几个重要方法:
- lock():获得锁,如果锁已经被占用,则等待
- lockInterruptibly():获得锁,但优先响应中断
- tryLock():尝试获得锁,成功返回true,失败返回false,该方法不等待,立即返回
- tryLock(long time,TimeUnit unit):在给定时间内尝试获得锁
- unlock():释放锁
*/
public class ReentrantLockDemo implements Runnable{
public static Integer i = 0;
public static ReentrantLock lock = new ReentrantLock(); @Override
public void run() {
for (int j = 0; j < 10000000; j++) {
lock.lock();
try {
i++;
}finally {
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException{
ReentrantLockDemo r = new ReentrantLockDemo();
Thread thread1 = new Thread(r);
Thread thread2 = new Thread(r);
thread1.start();thread2.start();
thread1.join();thread2.join();
System.out.println(i);//20000000
}
}

中断处理

import java.util.concurrent.locks.ReentrantLock;

/**
* 避免死锁
* 重入锁的中断处理能力
*/
public class IntLock implements Runnable{
public static ReentrantLock lock1 = new ReentrantLock();
public static ReentrantLock lock2 = new ReentrantLock();
int lock;
public IntLock(int lock) {
this.lock = lock;
}
@Override
public void run() {
try {
if (lock==1){
lock1.lockInterruptibly();
Thread.sleep(500);
lock2.lockInterruptibly();//可以对中断进行响应的锁
}else {
lock2.lockInterruptibly();
Thread.sleep(500);
lock1.lockInterruptibly(); //22行
}
}catch (InterruptedException e){
e.printStackTrace();
}finally {
//检查当前线程是否拥有该锁
if (lock1.isHeldByCurrentThread()) lock1.unlock();
if (lock2.isHeldByCurrentThread()) lock2.unlock();
System.out.println(Thread.currentThread().getId()+":线程退出");
}
}
public static void main(String[] args) throws InterruptedException{
IntLock i1 = new IntLock(1);
IntLock i2 = new IntLock(2);
Thread t1 = new Thread(i1);
Thread t2 = new Thread(i2);
t1.start();
t2.start();
Thread.sleep(1000);
t2.interrupt(); //中断t2 ,t2放弃对lock1的申请,同时释放已获得的lock2
//java.lang.InterruptedException
// at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)
// at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
// at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
// at com.combat.IntLock.run(IntLock.java:22)
// at java.lang.Thread.run(Thread.java:748)
//10:线程退出
//9:线程退出
}
}

限时等待

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; /**
* 限时等待锁
*/
public class TimeLockDemo implements Runnable{
public static ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
try {
if (lock.tryLock(5, TimeUnit.SECONDS)){ //等待时间,计时单位
Thread.sleep(6000);
}else {
System.out.println("get lock failed");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread())lock.unlock();
}
}
public static void main(String[] args){
TimeLockDemo demo = new TimeLockDemo();
Thread t1 = new Thread(demo);
Thread t2 = new Thread(demo);
t1.start();
t2.start();
}
//get lock failed
//由于占用锁的线程为6秒,另一个线程无法在5秒的等待时间内获得锁,因此请求锁失败
}
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; /**
* tryLock
* 限时等待锁 无参数 如果锁被其他线程占用,则当前线程不会进行等待,而是立即返回false,不会引起线程等待
*/
public class TimeLockDemo2 implements Runnable{
public static ReentrantLock lock1 = new ReentrantLock();
public static ReentrantLock lock2 = new ReentrantLock();
int lock;
public TimeLockDemo2(int lock) {
this.lock = lock;
}
@Override
public void run() {
if (lock == 1){
while (true){
if (lock1.tryLock()){
try {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (lock2.tryLock()){
try {
System.out.println(Thread.currentThread().getId()+":my job done");
return;
} finally {
lock2.unlock();
}
}
} finally {
lock1.unlock();
}
}
}
}else {
while (true){
if (lock2.tryLock()){
try {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (lock1.tryLock()){
try {
System.out.println(Thread.currentThread().getId()+":my job done");
return;
} finally {
lock1.unlock();
}
}
} finally {
lock2.unlock();
}
}
}
}
}
public static void main(String[] args){
TimeLockDemo2 r1 = new TimeLockDemo2(1);
TimeLockDemo2 r2 = new TimeLockDemo2(1);
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
//9:my job done
//10:my job done
}

公平锁

import java.util.concurrent.locks.ReentrantLock;

/**
* 公平锁
* synchronized产生的锁是非公平锁
* 重入锁可以设置公平性
*/
public class FairLock implements Runnable{
public static ReentrantLock lock = new ReentrantLock(true);
@Override
public void run() {
while (true){
try {
lock.lock();
System.out.println(Thread.currentThread().getName()+"获得锁");
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException{
FairLock lock = new FairLock();
Thread t1 = new Thread(lock, "thread_t1");
Thread t2 = new Thread(lock, "thread_t2");
t1.start();
t2.start();
}
//...
//thread_t2获得锁
//thread_t1获得锁
//thread_t2获得锁
//thread_t1获得锁
//thread_t2获得锁
//...
//两个线程基本交替获得锁 //而非公平锁,一个线程会倾向于再次获得已持有的锁,这种分配方式是高效的,但无公平性可言
}

20.ReenterLock重入锁的更多相关文章

  1. AQS学习(二) AQS互斥模式与ReenterLock可重入锁原理解析

    1. MyAQS介绍    在这个系列博客中,我们会参考着jdk的AbstractQueuedLongSynchronizer,从零开始自己动手实现一个AQS(MyAQS).通过模仿,自己造轮子来学习 ...

  2. 可重入锁(good)

    可重入锁,也叫做递归锁,是指在一个线程中可以多次获取同一把锁,比如:一个线程在执行一个带锁的方法,该方法中又调用了另一个需要相同锁的方法,则该线程可以直接执行调用的方法[即可重入],而无需重新获得锁: ...

  3. Java多线程——深入重入锁ReentrantLock

    简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为“独占锁”. ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychronized,是实现 ...

  4. 浅谈Java中的锁:Synchronized、重入锁、读写锁

    Java开发必须要掌握的知识点就包括如何使用锁在多线程的环境下控制对资源的访问限制 ◆ Synchronized ◆ 首先我们来看一段简单的代码: 12345678910111213141516171 ...

  5. synchronized 是可重入锁吗?为什么?

    什么是可重入锁? 关于什么是可重入锁,我们先来看一段维基百科的定义. 若一个程序或子程序可以“在任意时刻被中断然后操作系统调度执行另外一段代码,这段代码又调用了该子程序不会出错”,则称其为可重入(re ...

  6. JAVA锁机制-可重入锁,可中断锁,公平锁,读写锁,自旋锁,

    如果需要查看具体的synchronized和lock的实现原理,请参考:解决多线程安全问题-无非两个方法synchronized和lock 具体原理(百度) 在并发编程中,经常遇到多个线程访问同一个 ...

  7. Java多线程系列——深入重入锁ReentrantLock

    简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为“独占锁”. ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychronized,是实现 ...

  8. synchronized的功能拓展:重入锁(读书笔记)

     重入锁可以完全代替synchronized关键字.在JDK5.0的早期版本中,重入锁的性能远远好于synchronized,但是从JDK6.0开始.JDK在synchronized上做了大量的优化. ...

  9. redis实现分布式锁需要考虑的因素以及可重入锁实现

    死锁 错误例子 解决方式  防止死锁 通过设置超时时间  不要使用setnx key   expire 20  不能保证原子性 如果setnx程序就挂了 没有执行expire就死锁了  reidis2 ...

随机推荐

  1. Arrays.asList()报错java.lang.UnsupportedOperationException

    问题: 使用工具类Arrays.asList()方法把数组转换成集合时,不能使用修改集合相关的方法,比如add,remove.这个ArrayList是Arrays类自己定义的一个内部类!这个内部类没有 ...

  2. xampp 配置HTTPS

    参考:  https://blog.csdn.net/qq_35128576/article/details/81326524

  3. 报数问题:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位

    n = int(input("请输入人数:")) list_p = list(range(1,n+1)) #将所有人放在一个数字里面 count = 0 #设置一个变量,用户计算报 ...

  4. HDU 6073 Matching In Multiplication —— 2017 Multi-University Training 4

    Matching In Multiplication Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K ( ...

  5. 汉诺塔IX

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=76447#problem/E 汉诺塔IX Time Limit:1000MS     Me ...

  6. [CSP-S模拟测试]:喝喝喝(模拟)

    题目描述 奥利维尔和雪拉扎德在喝酒.两人连喝$18$瓶后,奥利维尔最终倒下了.奥利维尔服用了教会研究的醒酒药后,因为服用了太多产生了副作用,第二天睡不着了.他只好用数数的方式度过无聊的时光,不过他毕竟 ...

  7. python 中的__str__ 和__repr__方法

    看下面的例子就明白了 class Test(object): def __init__(self, value='hello, world!'): self.data = value >> ...

  8. 记.net3.5离线安装问题

    dism.exe /online /enable-feature /featurename:netfx3 /Source: X:\sourse\sxs pause 相关文件要相同版本的ISO中提取,否 ...

  9. configure error libmcrypt was not found解决方法

    安装到mcrypt的时候出现了问题./configure提示出错,首先提示*** Could not run libmcrypt test program, checking why-*** The ...

  10. 关于vsftp出现Restarting vsftpd (via systemctl): Job for vsftpd.service failed because the control 的解决办法

    转载于:http://blog.csdn.net/it_dream_er/article/details/50783111 刚刚在搭建ftp服务器时,在配置好一切的参数之后,在我重启时,出现了无法启动 ...