使用ReentrantLock实现同步

ReentrantLock对象的lock()方法获取锁, 调用unlock()方法释放锁

调用ReentrantLock对象的lock()方法的线程就持有"对象监视器",其他线程只有等待锁被释放时再次争抢。效果和使用synchronized关键字一样。

关键字synchronized与wait()和notify()/notifyAll()方法相结合可以实现等待/通知模式, 类ReentrantLock也可以实现同样的功能,但需要借助于Condition对象。Condition类是再jdk5中出现的技术,使用它有更好的灵活性,比如可以实现多路通知功能。使用ReentrantLock结合Condition类是可以实现"选择性通知",这个功能非常重要。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;public class MySservice {private ReentrantLock lock = new ReentrantLock();private Condition conditionA = lock.newCondition();private Condition conditionB = lock.newCondition();private boolean hasValue = false;public void set(){try {lock.lock();while(hasValue == true){System.out.println("setsetsetset"+Thread.currentThread().getName());conditionA.await();}System.out.println("set");hasValue = true;conditionB.signal();} catch (InterruptedException e) {e.printStackTrace();}finally {lock.unlock();}}public void get(){try {lock.lock();while(hasValue == false){System.out.println("getgetgetget");conditionB.await();}System.out.println("get");hasValue = false;conditionA.signal();} catch (InterruptedException e) {e.printStackTrace();}finally {lock.unlock();}}
}public class MyThreadA extends Thread {private MySservice mySservice;public MyThreadA(MySservice mySservice){super();this.mySservice = mySservice;}@Overridepublic void run(){for (int i = 0; i < Integer.MAX_VALUE; i++) {mySservice.set();}}
}public class MyThreadB extends Thread {private MySservice mySservice;public MyThreadB(MySservice mySservice){super();this.mySservice = mySservice;}@Overridepublic void run(){for (int i = 0; i < Integer.MAX_VALUE; i++) {mySservice.get();}}
}public class Run {public static void main(String[] args) {MySservice mySservice = new MySservice();MyThreadA[] myThreadA = new MyThreadA[10];MyThreadB[] myThreadB = new MyThreadB[10];for (int i = 0; i < 10; i++) {myThreadA[i] = new MyThreadA(mySservice);myThreadB[i] = new MyThreadB(mySservice);myThreadA[i].setName((i+1)+"");myThreadA[i].start();myThreadB[i].start();}}
}

方法getHoldCount()

该方法是查询当前线程保持此锁定的个数,也就是调用lock()方法的次数

import java.util.concurrent.locks.ReentrantLock;public class Service {private ReentrantLock lock = new ReentrantLock();public void serviceMethod1(){try{lock.lock();System.out.println("serviceMethod1 getHoldCount="+lock.getHoldCount());serviceMethod2();}finally {lock.unlock();}}public void serviceMethod2(){try{lock.lock();System.out.println("serviceMethod2 getHoldCount="+lock.getHoldCount());}finally {lock.unlock();}}
}public class Run {public static void main(String[] args) {Service service = new Service();service.serviceMethod1();}
}

方法getQueueLength()

返回正等待获取此锁定的线程估计数。

public class Run {public static void main(String[] args) throws InterruptedException {final Service service = new Service();Runnable runnable = new Runnable() {@Overridepublic void run() {service.serviceMethod1();}};Thread[] threadArray = new Thread[10];for (int i = 0; i < 10; i++) {threadArray[i] = new Thread(runnable);}for (int i = 0; i < 10; i++) {threadArray[i].start();}Thread.sleep(2000);System.out.println("有线程树:"+service.lock.getQueueLength()+"正在等待锁!");}
}import java.util.concurrent.locks.ReentrantLock;public class Service {public ReentrantLock lock = new ReentrantLock();public void serviceMethod1(){try{lock.lock();System.out.println("ThreadName="+Thread.currentThread().getName()+" 进入方法!");Thread.sleep(1000);}catch(InterruptedException ex){ex.printStackTrace();}finally {lock.unlock();}}
}

方法hasQueuedThread(), hasQueuedThreads()

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;public class Service {public ReentrantLock lock = new ReentrantLock();public Condition newCondition = lock.newCondition();public void waitMethod(){try{lock.lock();Thread.sleep(Integer.MAX_VALUE);}catch (InterruptedException ex){ex.printStackTrace();}finally {lock.unlock();}}
}public class Run {public static void main(String[] args) throws InterruptedException {final Service service = new Service();Runnable runnable = new Runnable() {@Overridepublic void run() {service.waitMethod();}};Thread threadA = new Thread(runnable);threadA.start();Thread.sleep(500);Thread threadB = new Thread(runnable);threadB.start();Thread.sleep(500);System.out.println(service.lock.hasQueuedThread(threadA));System.out.println(service.lock.hasQueuedThread(threadB));System.out.println(service.lock.hasQueuedThreads());System.out.println(service.lock.getQueueLength());}
}

方法isFair()

判断是不是公平锁

import java.util.concurrent.locks.ReentrantLock;public class Service {private ReentrantLock lock;public Service(boolean isFair){super();lock = new ReentrantLock(isFair);}public void serviceMethod(){try{lock.lock();System.out.println(Thread.currentThread().getName()+" 公平锁情况:"+lock.isFair());}finally {lock.unlock();}}
}public class Run {public static void main(String[] args) {Service service1 = new Service(true);Runnable runnable = new Runnable() {@Overridepublic void run() {service1.serviceMethod();}};Thread t1 = new Thread(runnable,"A");t1.start();Service service2 = new Service(false);Runnable runnable2 = new Runnable() {@Overridepublic void run() {service2.serviceMethod();}};Thread t2 = new Thread(runnable2,"B");t2.start();}
}

方法isHeldByCurrentThread()

查询当前线程是否保持此锁定

import java.util.concurrent.locks.ReentrantLock;public class Service {private ReentrantLock lock;public Service(){super();lock = new ReentrantLock();}public void serviceMethod(){try{System.out.println("当前线程是否保持此锁定"+lock.isHeldByCurrentThread());lock.lock();System.out.println("当前线程是否保持此锁定"+lock.isHeldByCurrentThread());}finally {lock.unlock();}}
}public class Run {public static void main(String[] args) {final Service service1 = new Service();Runnable runnable = new Runnable() {@Overridepublic void run() {service1.serviceMethod();}};Thread t = new Thread(runnable);t.start();}
}

方法tryLock(long timeout, TimeUnit unit)

如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;public class MyService {private ReentrantLock lock = new ReentrantLock();public void waitMethod(){try{if(lock.tryLock(3, TimeUnit.SECONDS)){System.out.println("    "+Thread.currentThread().getName()+"获得锁的时间:"+System.currentTimeMillis());Thread.sleep(10000);}else{System.out.println("    "+Thread.currentThread().getName()+"没有获得锁");}}catch (InterruptedException ex){ex.printStackTrace();}finally {if(lock.isHeldByCurrentThread()){lock.unlock();}}}
}public class Run {public static void main(String[] args) {final MyService service = new MyService();Runnable runnableRef = new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+" 调用waitMethod时间: "+System.currentTimeMillis());service.waitMethod();}};Thread threadA = new Thread(runnableRef);threadA.setName("A");threadA.start();Thread threadB = new Thread(runnableRef);threadB.setName("B");threadB.start();}
}

线程: ReentrantLock类相关推荐

  1. Java并发编程—线程同步类

    原文作者:洲洋1984 原文地址:Java 并发包中的高级同步工具 Java 中的并发包指的是 java.util.concurrent(简称 JUC)包和其子包下的类和接口,它为 Java 的并发提 ...

  2. ReentrantLock类源码解析

    先看ReentrantLock类的构造方法和成员 private final Sync sync;public ReentrantLock() {sync = new NonfairSync(); } ...

  3. 线程基类的构建与代码实践

    在C++中常用到线程来执行相应的任务,一般会构建一个线程基类,其他的线程类型通过继承的方式来实现不同的功能. 所实现的代码考虑了windows和linux平台的兼容性,且具有代表性,在工程实践中具有参 ...

  4. 线程工具类(根据电脑逻辑处理器个数控制同时运行的线程个数)

    代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst ...

  5. java线程组 线程池_JAVA多线程(三)-----线程组、线程池和线程相关类

    一.线程组和未处理的异常 Thread类提供了如下几个构造器来设置新创建的线程属于哪个线程组: Thread(ThreadGroup group,Runnable target):以target的ru ...

  6. java 重启线程_java 可重启线程及线程池类的设计(详解)

    了解JAVA多线程编程的人都知道,要产生一个线程有两种方法,一是类直接继承Thread类并实现其run()方法:二是类实现Runnable接口并实现其run()方法,然后新建一个以该类为构造方法参数的 ...

  7. 自定义线程池-线程池类和测试类编写

    package com.leon.demo01;import java.util.Collections; import java.util.LinkedList; import java.util. ...

  8. Larbin源代码分析[6]LARBIN中线程处理类

    一 线程类 larbin下的线程操作类,主要在mypthread.h中定义,实质上是利用宏定义,封装了pthread.h中的系统调用. 一个进程可以有多个线程,每个线程都有自己的处理流程. 二 具体实 ...

  9. Qt 学习之路 :Qt 线程相关类

      希望上一章有关事件循环的内容还没有把你绕晕.本章将重新回到有关线程的相关内容上面来.在前面的章节我们了解了有关QThread类的简单使用.不过,Qt 提供的有关线程的类可不那么简单,否则的话我们也 ...

最新文章

  1. 元组、列表、字典及集合练习
  2. IT规划的企业应用实践(10)研究的范围和限制
  3. 贝叶斯推断及其互联网应用(三):拼写检查
  4. python定时器 是线程吗_python线程定时器Timer(32)
  5. [机器学习]超参数优化算法-SuccessiveHalving与Hyperband
  6. 定制自己的Windows CE 5.0 ARM中文模拟器(转)
  7. Java学习之路 之 提问及解决篇
  8. Mysql设置允许外网访问
  9. 【干货篇】bilibili:基于 Flink 的机器学习工作流平台在 b 站的应用
  10. arm平台下的反汇编pdf_stm32逆向与安全科普,bin文件逆向反汇编
  11. 统计通话次数和时间的软件_通话时间统计手机下载-通话时间统计手机版下载v2.3-西西软件下载...
  12. mysql+tinyint+符号_mysql中TINYINT的取值范围
  13. PHP字符串函数strtolower(将字符串转化为小写)
  14. 真空扫街机行业调研报告 - 市场现状分析与发展前景预测
  15. 收藏!人工智能学习路径总结
  16. 如何把C盘里的文件默认位置更改到D盘指定目录?
  17. ISCC 2022 wp
  18. [爬虫01]爬虫基础
  19. java接口汽车品牌,88_熟练掌握ES Java API_对汽车品牌进行全文检索、精准查询和前缀搜索...
  20. 图像缩放--双线性内插法及其python实现(图文代码)

热门文章

  1. ACdream OJ 1140 Counting Triangles
  2. Xcode 3.2.5免证书开发调试[转]
  3. Flash与数学:球体曲面 (2)
  4. OpenGL中不可以有两个以上myDisplay函数,在主函数中生效的是最后调用的那个
  5. CCF-CSP 201703-1 试题名称: 分蛋糕
  6. 简单实现迷你Vue框架
  7. 生成模型学习笔记:从高斯判别分析到朴素贝叶斯
  8. 研究人员开发出最节能的 Wi-Fi 技术
  9. 利用shell监控cpu、磁盘、内存使用率
  10. Spring-AOP实践 - 统计访问时间