zl程序教程

您现在的位置是:首页 >  云平台

当前栏目

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

2023-09-11 14:16:10 时间

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

校对:方腾飞

监控Lock接口

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

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

准备

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

怎么做呢…

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

package tool;

import java.util.Collection;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

//1. 创建一个类,名为 MyLock ,扩展 ReentrantLock 类。

public class MyLock extends ReentrantLock {

 // 2. 实现 getOwnerName() 方法。此方法使用Lock类的保护方法 getOwner(), 返回控制锁的线程(如果存在)的名字。

 public String getOwnerName() {

 if (this.getOwner() == null) {

 return "None";

 return this.getOwner().getName();

 // 3. 实现 getThreads() 方法。此方法使用Lock类的保护方法 getQueuedThreads(),返回在锁里的线程的 queued

 // list。

 public Collection Thread getThreads() {

 return this.getQueuedThreads();

 // 4. 创建一个类,名为 Task,实现 Runnable 接口.

 public class Task implements Runnable {

 // 5. 声明一个私有 Lock 属性,名为 lock。

 private Lock lock;

 // 6. 实现类的构造函数,初始化它的属性值。

 public Task(Lock lock) {

 this.lock = lock;

 // 7. 实现 run() 方法。创建迭代5次的for循环。

 @Override

 public void run() {

 for (int i = 0; i i++) {

 // 8. 使用lock()方法获取锁,并打印一条信息。

 lock.lock();

 System.out.printf("%s: Get the Lock.\n", Thread.currentThread()

 .getName());

 // 9. 让线程休眠 500 毫秒。使用 unlock() 释放锁并打印一条信息。

 try {

 TimeUnit.MILLISECONDS.sleep(500);

 System.out.printf("%s: Free the Lock.\n", Thread

 .currentThread().getName());

 } catch (InterruptedException e) {

 e.printStackTrace();

 } finally {

 lock.unlock();

 // 10. 创建例子的主类通过创建一个类,名为 Main 并添加 main()方法。

 public static void main(String[] args) throws Exception {

 // 11. 创建 MyLock 对象,名为 lock。

 MyLock lock = new MyLock();

 // 12. 创建有5个Thread对象的 array。

 Thread threads[] = new Thread[5];

 // 13. 创建并开始5个线程来执行5个Task对象。

 for (int i = 0; i i++) {

 Task task = lock.new Task(lock);

 threads[i] = new Thread(task);

 threads[i].start();

 // 14. 创建迭代15次的for循环。

 for (int i = 0; i i++) {

 // 15. 把锁的拥有者的名字写入操控台。

 System.out.printf("Main: Logging the Lock\n");

 System.out.printf("************************\n");

 System.out.printf("Lock: Owner : %s\n", lock.getOwnerName());

 // 16. 显示锁queued的线程的号码和名字。

 System.out.printf("Lock: Queued Threads: %s\n",

 lock.hasQueuedThreads()); // 译者注:加上 System

 if (lock.hasQueuedThreads()) {

 System.out.printf("Lock: Queue Length: %d\n",

 lock.getQueueLength());

 System.out.printf("Lock: Queued Threads: ");

 Collection Thread lockedThreads = lock.getThreads();

 for (Thread lockedThread : lockedThreads) {

 System.out.printf("%s ", lockedThread.getName());

 System.out.printf("\n");

 // 17. 显示关于Lock对象的公平性和状态的信息。

 System.out.printf("Lock: Fairness: %s\n", lock.isFair());

 System.out.printf("Lock: Locked: %s\n", lock.isLocked());

 System.out.printf("************************\n");

 // 18. 让线程休眠1秒,并合上类的循环。

 TimeUnit.SECONDS.sleep(1);

它是如何工作的…

在这个指南里,你实现的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 值,表明锁是否为当前线程所拥有

参见

第二章,基本线程同步: 使用lock同步代码块
第七章,自定义同步类: 实现自定义锁

文章转自 并发编程网-ifeve.com


python接口自动化(二十八)--html测试 报告——下(详解) 上一篇我们批量执行完用例后,已经生成的测试报告是生成 HTML 格式的。但是我们可以看出那个官方的测试报告既不美观也不大方,我们这里需要优化一下,优化的让人赏心悦目,就和看到一个美女一样看了一眼,忍不住回头再多看一眼 - _ - 并且把上一篇遇到的问题列举解决一下。
使用aliyunECS服务器+宝塔面板部署springboot后端项目并测试接口 在部署过程中遇到了很多问题,解决起来也是十分繁琐,这里写个笔记记录一下遇到的问题和思路 这里我先打算测试以下后端接口,前端代码还没有进行运行。 还没有购买域名,因为域名需要备案时间要一周所以暂时使用公网ip进行访问。