测试并发应用 (一)监控Lock接口-阿里云开发者社区

开发者社区> ali清英> 正文

测试并发应用 (一)监控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 值,表明锁是否为当前线程所拥有

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java多线程高并发学习笔记(二)——深入理解ReentrantLock与Condition
锁的概念 从jdk发行1.5版本之后,在原来synchronize的基础上,增加了重入锁ReentrantLock。 本文就不介绍synchronize了,有兴趣的同学可以去了解一下,本文重点介绍ReentrantLock。
1073 0
Centos7下Docker上部署webgoat(用来演示Web应用程序中的典型安全漏洞的应用程序)
Centos7下Docker上部署webgoat(用来演示Web应用程序中的典型安全漏洞的应用程序)
655 0
Web防火墙应用场景:短信接口防刷
很多站长发现网站服务器变卡,短信注册接口费用大量增长,甚至注册用户被竞争对手精确营销,客户流失。 这是什么情况? 且听我们慢慢道来:
10749 0
Java泛型--泛型应用--泛型接口、泛型方法、泛型数组、泛型嵌套
<h1>1、泛型接口</h1> <h2>1.1泛型接口的基本概念</h2> <div> <img src="http://img.blog.csdn.net/20131016093459750" alt=""><br> </div> <div> <img src="http://img.blog.csdn.net/20131016093655937" alt=""><br> </di
1038 0
PHP中利用文件锁实现日志写入和网站接口访问等常见场景下的并发控制
针对并发环境下网站、日志文件写入产生的脏数据、更新丢失等情况的解决思路之一
2633 0
Java面向对象高级--抽象类与接口的应用
<h1>1、为抽象类和接口实例化</h1> <div> <img src="http://img.blog.csdn.net/20130928113110421" alt=""><br> </div> <div>抽象类和接口不能直接实例化,因为其内部包含了各个抽象方法,抽象方法本身都是未实现的方法,所以无法调用。通过对象多态性,子类发生了向上转型之后,所调用的全部方法都是被覆写过了的方
1317 0
+关注
ali清英
方腾飞,花名清英,英文名kiral,并发编程网创始人,支付宝技术专家,《Java并发编程的艺术》作者。
614
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载