线程: ReentrantLock类
使用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类相关推荐
- Java并发编程—线程同步类
原文作者:洲洋1984 原文地址:Java 并发包中的高级同步工具 Java 中的并发包指的是 java.util.concurrent(简称 JUC)包和其子包下的类和接口,它为 Java 的并发提 ...
- ReentrantLock类源码解析
先看ReentrantLock类的构造方法和成员 private final Sync sync;public ReentrantLock() {sync = new NonfairSync(); } ...
- 线程基类的构建与代码实践
在C++中常用到线程来执行相应的任务,一般会构建一个线程基类,其他的线程类型通过继承的方式来实现不同的功能. 所实现的代码考虑了windows和linux平台的兼容性,且具有代表性,在工程实践中具有参 ...
- 线程工具类(根据电脑逻辑处理器个数控制同时运行的线程个数)
代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst ...
- java线程组 线程池_JAVA多线程(三)-----线程组、线程池和线程相关类
一.线程组和未处理的异常 Thread类提供了如下几个构造器来设置新创建的线程属于哪个线程组: Thread(ThreadGroup group,Runnable target):以target的ru ...
- java 重启线程_java 可重启线程及线程池类的设计(详解)
了解JAVA多线程编程的人都知道,要产生一个线程有两种方法,一是类直接继承Thread类并实现其run()方法:二是类实现Runnable接口并实现其run()方法,然后新建一个以该类为构造方法参数的 ...
- 自定义线程池-线程池类和测试类编写
package com.leon.demo01;import java.util.Collections; import java.util.LinkedList; import java.util. ...
- Larbin源代码分析[6]LARBIN中线程处理类
一 线程类 larbin下的线程操作类,主要在mypthread.h中定义,实质上是利用宏定义,封装了pthread.h中的系统调用. 一个进程可以有多个线程,每个线程都有自己的处理流程. 二 具体实 ...
- Qt 学习之路 :Qt 线程相关类
希望上一章有关事件循环的内容还没有把你绕晕.本章将重新回到有关线程的相关内容上面来.在前面的章节我们了解了有关QThread类的简单使用.不过,Qt 提供的有关线程的类可不那么简单,否则的话我们也 ...
最新文章
- 元组、列表、字典及集合练习
- IT规划的企业应用实践(10)研究的范围和限制
- 贝叶斯推断及其互联网应用(三):拼写检查
- python定时器 是线程吗_python线程定时器Timer(32)
- [机器学习]超参数优化算法-SuccessiveHalving与Hyperband
- 定制自己的Windows CE 5.0 ARM中文模拟器(转)
- Java学习之路 之 提问及解决篇
- Mysql设置允许外网访问
- 【干货篇】bilibili:基于 Flink 的机器学习工作流平台在 b 站的应用
- arm平台下的反汇编pdf_stm32逆向与安全科普,bin文件逆向反汇编
- 统计通话次数和时间的软件_通话时间统计手机下载-通话时间统计手机版下载v2.3-西西软件下载...
- mysql+tinyint+符号_mysql中TINYINT的取值范围
- PHP字符串函数strtolower(将字符串转化为小写)
- 真空扫街机行业调研报告 - 市场现状分析与发展前景预测
- 收藏!人工智能学习路径总结
- 如何把C盘里的文件默认位置更改到D盘指定目录?
- ISCC 2022 wp
- [爬虫01]爬虫基础
- java接口汽车品牌,88_熟练掌握ES Java API_对汽车品牌进行全文检索、精准查询和前缀搜索...
- 图像缩放--双线性内插法及其python实现(图文代码)