测试并发应用 (一)监控Lock接口

声明:本文是《 Java 7 Concurrency Cookbook 》的第八章, 作者: Javier Fernández González 译者:郑玉婷  

校对:方腾飞

监控Lock接口

Lock 接口是Java 并发 API提供的最基本的机制来同步代码块。它允许定义临界区。临界区是代码块可以共享资源,但是不能被多个线程同时执行。此机制是通过Lock 接口和 ReentrantLock 类实现的。

在这个指南,你将学习从Lock对象可以获取的信息和如何获取这些信息。

准备

指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。

怎么做呢…

按照这些步骤来实现下面的例子:


001 package tool;
002 
003 import java.util.Collection;
004 import java.util.concurrent.TimeUnit;
005 import java.util.concurrent.locks.Lock;
006 import java.util.concurrent.locks.ReentrantLock;
007 
008//1.   创建一个类,名为 MyLock ,扩展 ReentrantLock 类。
009 public class MyLock extends ReentrantLock {
010 
011     // 2. 实现 getOwnerName() 方法。此方法使用Lock类的保护方法 getOwner(), 返回控制锁的线程(如果存在)的名字。
012     public String getOwnerName() {
013         if (this.getOwner() == null) {
014             return "None";
015         }
016         return this.getOwner().getName();
017     }
018 
019     // 3. 实现 getThreads() 方法。此方法使用Lock类的保护方法 getQueuedThreads(),返回在锁里的线程的 queued
020     // list。
021     public Collection<Thread> getThreads() {
022         return this.getQueuedThreads();
023     }
024 
025     // 4. 创建一个类,名为 Task,实现 Runnable 接口.
026     public class Task implements Runnable {
027 
028         // 5. 声明一个私有 Lock 属性,名为 lock。
029         private Lock lock;
030 
031         // 6. 实现类的构造函数,初始化它的属性值。
032         public Task(Lock lock) {
033             this.lock = lock;
034         }
035 
036         // 7. 实现 run() 方法。创建迭代5次的for循环。
037         @Override
038         public void run() {
039             for (int i = 0; i < 5; i++) {
040 
041                 // 8. 使用lock()方法获取锁,并打印一条信息。
042                 lock.lock();
043                 System.out.printf("%s: Get the Lock.\n", Thread.currentThread()
044                         .getName());
045 
046                 // 9. 让线程休眠 500 毫秒。使用 unlock() 释放锁并打印一条信息。
047                 try {
048                     TimeUnit.MILLISECONDS.sleep(500);
049                     System.out.printf("%s: Free the Lock.\n", Thread
050                             .currentThread().getName());
051                 } catch (InterruptedException e) {
052                     e.printStackTrace();
053                 } finally {
054                     lock.unlock();
055                 }
056             }
057         }
058     }
059 
060     // 10. 创建例子的主类通过创建一个类,名为 Main 并添加 main()方法。
061     public static void main(String[] args) throws Exception {
062 
063         // 11. 创建 MyLock 对象,名为 lock。
064         MyLock lock = new MyLock();
065 
066         // 12. 创建有5个Thread对象的 array。
067         Thread threads[] = new Thread[5];
068 
069         // 13. 创建并开始5个线程来执行5个Task对象。
070         for (int i = 0; i < 5; i++) {
071             Task task = lock.new Task(lock);
072             threads[i] = new Thread(task);
073             threads[i].start();
074         }
075 
076         // 14. 创建迭代15次的for循环。
077         for (int i = 0; i < 15; i++) {
078 
079             // 15. 把锁的拥有者的名字写入操控台。
080             System.out.printf("Main: Logging the Lock\n");
081             System.out.printf("************************\n");
082             System.out.printf("Lock: Owner : %s\n", lock.getOwnerName());
083 
084             // 16. 显示锁queued的线程的号码和名字。
085             System.out.printf("Lock: Queued Threads: %s\n",
086                     lock.hasQueuedThreads()); // 译者注:加上 System
087             if (lock.hasQueuedThreads()) {
088                 System.out.printf("Lock: Queue Length: %d\n",
089                         lock.getQueueLength());
090                 System.out.printf("Lock: Queued Threads: ");
091                 Collection<Thread> lockedThreads = lock.getThreads();
092                 for (Thread lockedThread : lockedThreads) {
093                     System.out.printf("%s ", lockedThread.getName());
094                 }
095                 System.out.printf("\n");
096             }
097 
098             // 17. 显示关于Lock对象的公平性和状态的信息。
099             System.out.printf("Lock: Fairness: %s\n", lock.isFair());
100             System.out.printf("Lock: Locked: %s\n", lock.isLocked());
101             System.out.printf("************************\n");
102 
103             // 18. 让线程休眠1秒,并合上类的循环。
104             TimeUnit.SECONDS.sleep(1);
105         }
106     }
107}

它是如何工作的…

在这个指南里,你实现的MyLock类扩展了ReentrantLock类来返回信息,除此之外获得不到这些信息 ,因为ReentrantLock 类里的数据都是保护类型的。 通过MyLock类实现的方法:

  • getOwnerName():只有唯一一个线程可以执行被Lock对象保护的临界区。锁存储了正在执行临界区的线程。此线程会被ReentrantLock类的保护方法 getOwner()返回。 此方法使用 getOwner() 方法来返回线程的名字。
  • getThreads():当线程正在执行临界区时,其他线程尝试进入临界区就会被放到休眠状态一直到他们可以继续执行为止。ReentrantLock类保护方法getQueuedThreads() 返回 正在等待执行临界区的线程list。此方法返回 getQueuedThreads() 方法返回的结果。

我们还使用了 ReentrantLock 类里实现的其他方法:

  • hasQueuedThreads():此方法返回 Boolean 值表明是否有线程在等待获取此锁
  • getQueueLength(): 此方法返回等待获取此锁的线程数量
  • isLocked(): 此方法返回 Boolean 值表明此锁是否为某个线程所拥有
  • isFair(): 此方法返回 Boolean 值表明锁的 fair 模式是否被激活

更多…

ReentrantLock 类还有其他方法也是用来获取Lock对象的信息的:

  • getHoldCount(): 返回当前线程获取锁的次数
  • isHeldByCurrentThread(): 返回 Boolean 值,表明锁是否为当前线程所拥有

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[There will be more story......]

This blog will keep on updating.转载于:https://www.cnblogs.com/SinGuLaRiTy2001/p/7965776.html

根据生日得到星座

--得到星座 function DataCenter_Setting:GetConstellation(month, day)local dataInfo {121, 220, 321, 421, 522, 622, 723, 824, 924, 1024, 1123, 1222}local Constellations {"水瓶", "双鱼", "白羊", "金牛", "双子"…

[转]Android 项目的代码混淆,Android proguard 使用说明

简介 Java代码是非常容易反编译的。为了很好的保护Java源代码&#xff0c;我们往往会对编译好的class文件进行混淆处理。 ProGuard是一个混淆代码的开源项目。它的主要作用就是混淆&#xff0c;当然它还能对字节码进行缩减体积、优化等&#xff0c;但那些对于我们来说都算是次要…

数据结构与算法:终于可以用三种语言(C,C#,JavaScript)把图的广度优先遍历讲清楚了(推荐收藏)

文章目录邻接矩阵存储图的广度优先遍历过程分析C语言实现队列编程程序中加入图的处理函数结果的再次分析C#语言实现图的广度优先遍历、并显示广度优先遍历生成树JavaScript语言实现图的广度优先遍历、并显示广度优先遍历生成树邻接矩阵存储图的广度优先遍历过程分析 对图1这样…

C语言试题161之求100000以内的自守数

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:自守数是…

改造.NET遗留应用

浅议.NET遗留应用改造TLDR&#xff1a;本文介绍了遗留应用改造中的一些常见问题&#xff0c;并对改造所能开展的目标、原则、策略进行了概述。一、背景概述1、概述或许仅“遗留应用”这个标题就比较吸睛&#xff0c;因为我听过太多人吐槽了。Robert Martin在《修改代码的艺术》…

GitHub的DGit改进了平台的可靠性、性能以及可用性

GitHub最近悄悄地发布了DGit&#xff0c;全称为“分布式Git”。这是一种基于Git创建的分布式存储系统&#xff0c;其目标是改进使用GitHub时的可靠性、可用性以及性能。\\DGit是一个应用层面的协议&#xff0c;它利用了Git分布式的特性&#xff0c;将每个仓库在三台不同的、独立…

用静态NAT实现外网PC访问内网服务器

在我们的生产环境中常常处于安全考虑将服务器置于内网环境中&#xff0c;但同时得向外网提供各种服务功能&#xff0c;此时就需要用到NAT技术。下面是我用思科的仿真软件搭建的一个实验环境&#xff0c;实现外网PC访问内网服务器。先说明一下实验环境&#xff1a;路由器R0左边为…

[转]分布式事务之TCC服务设计和实现注意事项

1、TCC简介 TCC是一种比较成熟的分布式事务解决方案&#xff0c;可用于解决跨库操作的数据一致性问题&#xff1b; TCC是服务化的两阶段编程模型&#xff0c;其Try、Confirm、Cancel 3个方法均由业务编码实现&#xff1b; 其中Try操作作为一阶段&#xff0c;负责资源的检查和…

量化投资策略的评估标准及其计算公式

收益率指标&#xff1a;分为策略的总收益率和策略的年化收益率 策略的总收益率&#xff1a; 策略的总收益率是评价一个策略盈利能力的最基本的指标&#xff0c;其计算方法为&#xff1a; 公式中Vt表示策略最终的股票和现金的总价值&#xff0c;V0表示策略最初的股票和现金的总…

.net post xml 数据

var request WebRequest.Create(url);//url 是post 接口的URL request.Method "post";// 请求方法 request.ContentType "text/xml"; //请求类型 request.Headers.Add("charset:utf-8"); //设置文档类型的编码格式 var encoding Encoding.Ge…

【ArcGIS微课1000例】0005:空间连接(Spatial Join)

问题描述 现在要根据范围,怎样批量统计各个范围内的湖泊的总面积、各个省份内的铁路或河流总长度、各个地区的人口综合等。 空间连接 根据空间关系将一个要素类的属性连接到另一个要素类的属性。目标要素和来自连接要素的被连接属性写入到输出要素类。 用法 空间连接是指根…

【微服务专题之】.Net6中集成消息队列-RabbitMQ中直接路由模式

微信公众号&#xff1a;趣编程ACE关注可了解更多的.NET日常实战开发技巧&#xff0c;如需源码 请公众号后台留言 源码;[如果觉得本公众号对您有帮助&#xff0c;欢迎关注]前文回顾【微服务专题之】.Net6下集成消息队列上-RabbitMQ【微服务专题之】.Net6下集成消息队列2-RabbitM…

C语言试题162之圆周率π

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:圆周率π…

第14、15教学周作业

要求一 还差一些没做完。 要求二 USTH_C程序设计&#xff08;基础&#xff09;14周第一次PTA作业 7-3 将数组中的数逆序存放 1.实验代码 #include<stdio.h>int main() {int i,n,t;scanf("%d",&n);int a[n];for(i0;i<n;i){scanf("%d",&t)…

篇三:访问JSON静态文件

背景&#xff1a;在定位的时候带出车牌号的前两位&#xff0c;这里就有一个地址和车牌号前两位的映射关系&#xff0c;这个映射关系起初是通过Ajax在页面加载的时候请求去数据库里面查出来赋给一个变量&#xff0c;然后去操作&#xff0c;但是这个过程通常需要4~7秒&#xff0c…

代理(Proxy)

2019独角兽企业重金招聘Python工程师标准>>> 一、代理的概念 动态代理技术是整个java技术中最重要的一个技术&#xff0c;它是学习java框架的基础&#xff0c;不会动态代理技术&#xff0c;那么在学习Spring这些框架时是学不明白的。 动态代理技术就是用来产生一个对…

【ArcGIS微课1000例】0006:创建随机点(Create Random Points)

问题描述 在一个给定的范围内,根据随机位置,生成指定数量的随机点。生成的随机点通常用来提取每个点对应的NDVI,高程,气温等值。 ArcGIS创建随机点 创建指定数量的随机点要素。可以在范围窗口中、面要素内、点要素上或线要素沿线生成随机点。 工具介绍:

C语言试题163之计算某一天是对应年的第几天,这一年一共多少天;计算两个日期之间相隔的天数。两个日期由键盘输入。

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:计算某一…

[转]《吐血整理》系列-顶级程序员工具集

你知道的越多&#xff0c;你不知道的越多 点赞再看&#xff0c;养成习惯 GitHub上已经开源 https://github.com/JavaFamily 有一线大厂面试点脑图、个人联系方式&#xff0c;欢迎Star和指教 前言 这期是被人才群交流里&#xff0c;还有很多之前网友评论强行顶出来的一期&#x…