测试并发应用(八)配置NetBeans来调试并发代码

简介:

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

配置NetBeans来调试并发代码

在当今世界,软件开发的应用必须工作正常,要达到公司的质量标准,还要在将来可以很容易的修改,而且不仅要在有限的时间内,还要尽可能低的费用支出。为了到达这个目标,必需使用 IDE,它集合了一个公共接口和多个工具(编译器和调试器)为了方便应用程序的开发。

如果你使用 Java 编程语言,那么 NetBeans 是最普遍的 IDE之一。它有一个内置调试器(integrated debugger)允许你调试你的应用。在这个指南,你将学习如何改变配置来帮助测试并发应用。

准备

你应该安装好 NetBeans IDE 。打开并创建一个新的Java项目。

怎么做呢…

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

01 //1.   创建一个类,名为 Task1,并一定实现 Runnable 接口。
02 public class Task1 implements Runnable {
03  
04 //2.   声明2个私有 Lock 属性,名为 lock1 和 lock2。
05 private Lock lock1, lock2;
06  
07 //3.   实现类的构造函数,初始化它的属性值。
08 public Task1 (Lock lock1, Lock lock2) {
09     this.lock1=lock1;
10     this.lock2=lock2;
11 }
12  
13 //4.   实现 run() 方法。首先,使用 lock() 方法来获取 lock1 对象的控制,并写信息到操控台表明已经获得了。
14 @Override
15 public void run() {
16 lock1.lock();
17 System.out.printf("Task 1: Lock 1 locked\n");
18  
19 //5. 然后,使用 lock() 方法来获取 lock2 对象的控制,并写信息到操控台表明已经获得了。
20 lock2.lock();
21 System.out.printf("Task 1: Lock 2 locked\n");
22 //最后,释放这2个lock对象。先是 lock2 对象,然后 lock1 对象。
23 lock2.unlock();
24 lock1.unlock();
25 }
26  
27 //6.  创建一个类,名为 Task2,并一定实现 Runnable 接口.
28 public class Task2 implements Runnable{
29  
30 //7.    声明2个私有 Lock 属性,名为 lock1 和 lock2。
31 private Lock lock1, lock2;
32  
33 //8.  实现类的构造函数,初始化它的属性值。
34 public Task2(Lock lock1, Lock lock2) {
35     this.lock1=lock1;
36     this.lock2=lock2;
37 }
38  
39 //9.   实现 run() 方法。首先,使用 lock() 方法来获取 lock2 对象的控制,并写信息到操控台表明已经获得了。
40 @Override
41 public void run() {
42 lock2.lock();
43 System.out.printf("Task 2: Lock 2 locked\n");
44  
45 //10. 然后,使用 lock() 方法来获取 lock1 对象的控制,并写信息到操控台表明已经获得了。
46 lock1.lock();
47 System.out.printf("Task 2: Lock 1 locked\n");
48  
49 //11. 最后,释放这2个lock对象。先是 lock1 对象,然后 lock2 对象。
50 lock1.unlock();
51 lock2.unlock();
52 }
53  
54 //12. 创建例子的主类通过创建一个类,名为 Main 并添加 main()方法。
55 public class Main {
56  
57 //13. 声明2个私有 Lock 属性,名为 lock1 和 lock2。
58 Lock lock1, lock2;
59 lock1=new ReentrantLock();
60 lock2=new ReentrantLock();
61  
62 //14. 创建 Task1 对象,名为 task1。
63 Task1 task1=new Task1(lock1, lock2);
64  
65 //15. 创建 Task2 对象,名为 task2。
66 Task2 task2=new Task2(lock1, lock2);
67  
68 //16. 使用2个线程执行这2个 tasks。
69 Thread thread1=new Thread(task1);
70 Thread thread2=new Thread(task2);
71  
72 thread1.start();
73 thread2.start();
74  
75 //17.  当2个任务还没有结束他们的运行,每500毫秒就写一条信息给操控台。使用 isAlive() 方法来检查线程是否结束运行。
76 while ((thread1.isAlive()) &&(thread2.isAlive())) {
77     System.out.println("Main: The example is""running");
78     try {
79         TimeUnit.MILLISECONDS.sleep(500);
80     catch (InterruptedException ex) {
81         ex.printStackTrace();
82     }
83 }

18. 添加一个breakpoint到 Task1 类的run()方法 里的第一个 println() 方法的调用。class.

19.调试此程序。你可以发现 Debugging 窗口在 NetBeans 的主窗口的左上角。以下的裁图呈现的窗口外观里Task1对象 由于到达了breakpoint,所以进入休眠,而其他的线程还在运行:

20. 暂停主线程的运行。选择线程,右键单击,然后线程Suspend选项。以下的裁图展示的是新的Debugging窗口外观。请看下面的裁图:

21. 恢复被暂停的2个线程。选择每个线程,右键单击,选择Resume选项。

它是如何工作的…

当使用 NetBeans 试调并发应用, 当试调器到达 breakpoint, 它暂停到达 breakpoint 的线程并在左上角的 Debugging 窗口显示当前正在运行的线程。

你可以使用窗口来暂停或者恢复当前在 Pause 或者 Resume选项中运行的线程。你也可以使用 Variables 标签来查看线程的变量或者属性的值。

NetBeans 也包含了 deadlock 检测器。当你在 Debug 菜单选择 Check for Deadlock 选项,NetBeans 执行对应用的分析来试调决定是否有deadlock 情况。这个例子是很明显的 deadlock。第一个线程首先获得锁lock1,然后锁lock2。第二个线程获得锁与第一个相反的顺序。breakpoint的插入导致了deadlock,但是如果你使用 NetBeans deadlock检测器,你什么也不会发现,所以应该慎重使用此选项。

使用 同步关键词 改变在2个任务中的锁,并再次调试程序。Task1的代码如以下的代码:

1 @Override
2 public void run() {
3 synchronized(lock1) {
4     System.out.printf("Task 1: Lock 1 locked\n");
5 synchronized(lock2) {
6     System.out.printf("Task 1: Lock 2 locked\n");
7 }
8 }
9 }

Task2类的代码跟这个类似,只是改变了locks的顺序。如果你再此调试这个例子,你会再次得到deadlock,但是在这次方案,是被deadlock检测器检查到的,如你在以下裁图中看到的:

更多…

有一些控制debugger的选项。在Tools 菜单选择 Options 选项。然后,选择 Miscellaneous 选项,和 Java Debugger 标签。以下截图是窗口的外观:

在窗口中有2个选项可以控制之前描述的行为:

新 breakpoints 暂停:这个选项,你配置NetBeans的在线程中寻找breakpoint的行为。你可以只暂停有breakpoint的线程或者应用的全部线程。
步骤恢复:这个选项,你配置NetBeans恢复一个线程时的行为。你可以只恢复当前线程或者全部线程。2个选项都在之前的展示的裁图中标明了。

参见

第八章,测试并发应用:配置Eclipse来调试并发代码

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

目录
相关文章
|
23天前
|
SQL 安全 测试技术
【软件设计师备考 专题 】测试要求说明书的编写和应用
【软件设计师备考 专题 】测试要求说明书的编写和应用
54 0
|
24天前
|
Java 关系型数据库 数据库连接
Mybatis+MySQL动态分页查询数据经典案例(含代码以及测试)
Mybatis+MySQL动态分页查询数据经典案例(含代码以及测试)
23 1
|
1月前
|
Web App开发 前端开发 测试技术
探索自动化测试工具:Selenium的威力与应用
探索自动化测试工具:Selenium的威力与应用
探索自动化测试工具:Selenium的威力与应用
|
28天前
|
安全 测试技术
现代软件测试中的自动化技术应用及挑战
在当今数字化时代,软件测试的重要性日益凸显。本文探讨了现代软件测试中自动化技术的应用现状和挑战,分析了自动化测试在提高效率、降低成本、增强可靠性等方面的优势,同时也提出了自动化测试所面临的挑战和解决方案。
|
1月前
|
机器学习/深度学习 数据采集 人工智能
探索AI在软件测试中的应用与挑战
【2月更文挑战第25天】 随着人工智能(AI)技术的迅猛发展,其在软件测试领域的应用逐渐深入。AI不仅改变了传统测试流程,提高了测试效率和质量,也引入了新的挑战。本文将详细探讨AI在软件测试中的具体应用,包括智能化测试用例生成、缺陷预测、自动化测试执行等,并分析当前面临的主要挑战,如数据质量、模型泛化能力和工具集成等问题。通过实例分析和研究展望,本文旨在为软件测试专业人士提供一个关于AI技术融合的全面视角。
|
1月前
|
机器学习/深度学习 数据采集 人工智能
探索AI在软件测试中的应用和优势
【2月更文挑战第22天】 随着科技的不断发展,人工智能(AI)在各个领域的应用越来越广泛。本文主要探讨了AI在软件测试领域的应用及其带来的优势。文章首先介绍了AI技术的基本概念,然后详细分析了AI在软件测试中的具体应用,包括自动化测试、智能缺陷检测和预测等方面。最后,文章总结了AI在软件测试领域的优势,如提高测试效率、降低人力成本、提高测试质量等,并展望了AI在软件测试领域的未来发展趋势。
|
19天前
|
Web App开发 Java 测试技术
深入理解与应用软件自动化测试工具Selenium
随着软件开发的快速发展,软件测试在保证产品质量方面发挥着越来越重要的作用。其中,自动化测试以其效率高、成本低的特点受到了广大开发者的欢迎。本文主要介绍了自动化测试工具Selenium的基本概念、原理以及在实际开发中的应用,旨在帮助读者更好地理解和使用Selenium进行高效的自动化测试。
22 4
|
24天前
|
设计模式 敏捷开发 监控
深入理解与应用软件自动化测试框架
在快速迭代的软件开发过程中,自动化测试已成为确保产品质量和加快交付速度的关键因素。本文将详细探讨自动化测试框架的核心原理、设计模式及其在实际项目中的应用。我们将分析几种流行的自动化测试工具,如Selenium、Appium和JUnit,并讨论它们如何集成以形成强大的测试解决方案。文章还将展示通过自定义框架来满足特定测试需求的实例,以及如何通过持续集成和持续部署(CI/CD)流程优化测试实践。
|
27天前
|
缓存 运维 Serverless
应用研发平台EMAS产品常见问题之测试检查更新没有反应如何解决
应用研发平台EMAS(Enterprise Mobile Application Service)是阿里云提供的一个全栈移动应用开发平台,集成了应用开发、测试、部署、监控和运营服务;本合集旨在总结EMAS产品在应用开发和运维过程中的常见问题及解决方案,助力开发者和企业高效解决技术难题,加速移动应用的上线和稳定运行。
|
28天前
|
敏捷开发 供应链 测试技术
深入理解与应用软件测试中的Mock技术
【2月更文挑战第30天】 在现代软件开发过程中,单元测试是保证代码质量的重要手段。然而,对于高度依赖外部系统或服务的应用来说,传统的单元测试方法往往难以实施。Mock技术应运而生,它通过模拟外部依赖的响应,使开发者可以在隔离的环境中测试目标代码。本文将探讨Mock技术的概念、应用场景以及如何在软件测试中有效地使用Mock对象,以增强测试的灵活性和可靠性。