2019独角兽企业重金招聘Python工程师标准>>>

链接地址:http://www.xx566.com/detail/154.html

上一篇Guava库学习:学习Concurrency(二)Monitor_1中,我们简单的介绍了一下Guava Concurrency Monitor监控类,并对Monitor的源码结构进行了分析,对Monitor中的一些重要的方法做了简单的整理,那么在实际的工作中我们又该怎样去应用Monitor呢?接下来,我们首先通过分析GitHub上面的开源代码,来继续进行Guava Concurrency Monitor的学习。

下面的开源代码:包含Monitor的实例代码MonitorExample和对应的测试类MonitorExampleTest,由于针对的是Guava较早的版本,所以其中的一些API已经舍弃,不过仍然具有很高的学习价值,代码如下:

package guava;import com.google.common.util.concurrent.Monitor;import java.util.concurrent.atomic.AtomicInteger;/*** 原文地址:https://gist.github.com/bbejeck/1369371* User: bbejeck*/
public class MonitorExample {private final Monitor monitor = new Monitor();private volatile boolean condition = true;private int taskDoneCounter;//AtomicInteger:线程安全的加减操作private AtomicInteger taskSkippedCounter = new AtomicInteger(0);private int stopTaskCount;private Monitor.Guard conditionGuard = new Monitor.Guard(monitor) {@Overridepublic boolean isSatisfied() {return condition;}};public void demoTryEnterIf() throws InterruptedException {if (monitor.tryEnterIf(conditionGuard)) {try {simulatedWork();taskDoneCounter++;} finally {monitor.leave();}} else {//自增加1taskSkippedCounter.incrementAndGet();}}public void demoEnterIf() throws InterruptedException {if (monitor.enterIf(conditionGuard)) {try {taskDoneCounter++;if (taskDoneCounter == stopTaskCount) {condition = false;}} finally {monitor.leave();}} else {taskSkippedCounter.incrementAndGet();}}public void demoEnterWhen() throws InterruptedException {monitor.enterWhen(conditionGuard);try {taskDoneCounter++;if (taskDoneCounter == stopTaskCount) {condition = false;}} finally {monitor.leave();}}private void simulatedWork() throws InterruptedException {Thread.sleep(250);}//    public void reEvaluateGuardCondition() {
//        monitor.reevaluateGuards();
//    }public int getStopTaskCount() {return stopTaskCount;}public void setStopTaskCount(int stopTaskCount) {this.stopTaskCount = stopTaskCount;}public void setCondition(boolean condition) {this.condition = condition;}public int getTaskSkippedCounter() {return taskSkippedCounter.get();}public int getTaskDoneCounter() {return taskDoneCounter;}
}
package guava;import org.junit.After;
import org.junit.Before;
import org.junit.Test;import java.lang.reflect.Method;
import java.util.concurrent.*;import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;/*** 原文地址:https://gist.github.com/bbejeck/1369371* User: bbejeck*/
public class MonitorExampleTest {private MonitorExample monitorExample;private ExecutorService executorService;private int numberThreads = 10;// CountDownLatch:同步辅助类,允许一个或多个线程等待其他线程所执行的一组操作完成private CountDownLatch startSignal;private CountDownLatch doneSignal;@Beforepublic void setUp() throws Exception {monitorExample = new MonitorExample();executorService = Executors.newFixedThreadPool(numberThreads);startSignal = new CountDownLatch(1);doneSignal = new CountDownLatch(numberThreads);}@Afterpublic void tearDown() {executorService.shutdownNow();}/*** 第一个线程会进入Monitor调用simulatedWork()后线程等待* 其余9个线程则会进入else,对taskSkippedCounter自增** @throws Exception*/@Testpublic void testDemoTryEnterIf() throws Exception {setUpThreadsForTestingMethod("demoTryEnterIf");startAllThreadsForTest();waitForTestThreadsToFinish();int expectedTaskCount = 1;int expectedSkippedTasks = 9;assertThat(monitorExample.getTaskDoneCounter(), is(expectedTaskCount));assertThat(monitorExample.getTaskSkippedCounter(), is(expectedSkippedTasks));}/*** 前5个线程会等待Monitor,因为Guard的isSatisfied()为true* 但是一旦isSatisfied()变为false,剩余的线程会进入else,* 对taskSkippedCounter自增** @throws Exception*/@Testpublic void testDemoEnterIfOnlyFiveTasksComplete() throws Exception {monitorExample.setStopTaskCount(5);setUpThreadsForTestingMethod("demoEnterIf");startAllThreadsForTest();waitForTestThreadsToFinish();int expectedTaskCount = 5;int expectedSkippedTasks = 5;assertThat(monitorExample.getTaskDoneCounter(), is(expectedTaskCount));assertThat(monitorExample.getTaskSkippedCounter(), is(expectedSkippedTasks));}/*** 所有10个线程都会进入Monitor,因为在整个时间内Guard的isSatisfied()为true** @throws Exception*/@Testpublic void testDemoEnterIfAllTasksComplete() throws Exception {monitorExample.setStopTaskCount(Integer.MAX_VALUE);setUpThreadsForTestingMethod("demoEnterIf");startAllThreadsForTest();waitForTestThreadsToFinish();int expectedTaskCount = 10;int expectedSkippedTasks = 0;assertThat(monitorExample.getTaskDoneCounter(), is(expectedTaskCount));assertThat(monitorExample.getTaskSkippedCounter(), is(expectedSkippedTasks));}/*** Guard的isSatisfied()初始化为true,但是所有10个线程会进入Monitor** @throws Exception*/@Testpublic void testDemoEnterWhen() throws Exception {monitorExample.setStopTaskCount(Integer.MAX_VALUE);monitorExample.setCondition(false);setUpThreadsForTestingMethod("demoEnterWhen");startAllThreadsForTest();int expectedCompletedCount = 0;int completedCount = monitorExample.getTaskDoneCounter();assertThat(completedCount, is(expectedCompletedCount));monitorExample.setCondition(true);waitForTestThreadsToFinish();expectedCompletedCount = 10;completedCount = monitorExample.getTaskDoneCounter();assertThat(completedCount, is(expectedCompletedCount));}/*** 在3个线程完成工作后,人为的设置Guard的isSatisfied()为false* 以证明剩余的7个线程将等待,直到isSatisfied()变为true* 然后才会进入Monitor.** @throws Exception*/@Testpublic void testDemoEnterWhenAllTasksCompleteEvenWhenConditionChanges() throws Exception {monitorExample.setCondition(true);monitorExample.setStopTaskCount(3);setUpThreadsForTestingMethod("demoEnterWhen");startAllThreadsForTest();//验证最初只有3个线程工作, 重新设定Guard的isSatisfied()为trueFutureTask<Integer> checkInitialTasksCompleted = new FutureTask<Integer>(new Callable<Integer>() {public Integer call() {int initialCompletedTasks = monitorExample.getTaskDoneCounter();monitorExample.setCondition(true);
//                        monitorExample.reEvaluateGuardCondition();return initialCompletedTasks;}});new Thread(checkInitialTasksCompleted).start();int expectedCompletedCount = 3;int completedCount = checkInitialTasksCompleted.get();assertThat(completedCount, is(expectedCompletedCount));waitForTestThreadsToFinish();assertThat(completedCount, is(expectedCompletedCount));expectedCompletedCount = 10;completedCount = monitorExample.getTaskDoneCounter();assertThat(completedCount, is(expectedCompletedCount));}private void waitForTestThreadsToFinish() throws InterruptedException {doneSignal.await(1000l, TimeUnit.MILLISECONDS);}private void startAllThreadsForTest() {startSignal.countDown();}private Method getMethodUnderTest(String methodName) throws Exception {return monitorExample.getClass().getDeclaredMethod(methodName);}private void setUpThreadsForTestingMethod(String methodName) throws Exception {final Method testMethod = getMethodUnderTest(methodName);for (int i = 0; i < numberThreads; i++) {executorService.execute(new Runnable() {@Overridepublic void run() {try {startSignal.await();testMethod.invoke(monitorExample);} catch (Exception e) {//异常无须处理} finally {doneSignal.countDown();}}});}}}

转载于:https://my.oschina.net/realfighter/blog/349926

Guava库学习:学习Concurrency(二)Monitor_2相关推荐

  1. Guava库学习:学习Guava EventBus(二)EventBus 事件订阅示例

    2019独角兽企业重金招聘Python工程师标准>>> 原文地址:Guava库学习:学习Guava EventBus(二)EventBus 事件订阅示例 上一篇Guava库学习:学习 ...

  2. Guava库学习:学习Concurrency(九)RateLimiter

    2019独角兽企业重金招聘Python工程师标准>>> 链接地址:http://www.xx566.com/detail/164.html 上一篇,Guava库学习:学习Concur ...

  3. Huggingface Transformers库学习笔记(二):使用Transformers(上)(Using Transformers Part 1)

    前言 本部分是Transformer库的基础部分的上半部分,主要包括任务汇总.模型汇总和数据预处理三方面内容,由于许多模型我也不太了解,所以多为机器翻译得到,错误再所难免,内容仅供参考. Huggin ...

  4. [pytorch] PyTorch Metric Learning库代码学习二 Inference

    PyTorch Metric Learning库代码学习二 Inference Install the packages Import the packages Create helper funct ...

  5. Boost库学习笔记(二)算法模块-C++11标准

    Boost库学习笔记(二)算法模块-C++11标准 一.综述 Boost.Algorithm是一系列人通用推荐算法的集合,虽然有用的通用算法很多,但是为了保证质量和体积,并不会将太多通用算法通过审查测 ...

  6. C++语言学习(十二)——C++语言常见函数调用约定

    C++语言学习(十二)--C++语言常见函数调用约定 一.C++语言函数调用约定简介 C /C++开发中,程序编译没有问题,但链接的时候报告函数不存在,或程序编译和链接都没有错误,但只要调用库中的函数 ...

  7. Python学习笔记(二):标准流与重定向

    Python学习笔记(二):标准流与重定向 - SamWei - 博客园 Python学习笔记(二):标准流与重定向 Posted on 2012-02-19 22:36 SamWei 阅读(176) ...

  8. opencv学习笔记(二):基于肤色的人手检测

    opencv学习笔记(二):基于肤色的人手检测 原文:http://blog.csdn.net/wzmsltw/article/details/50849810 先写了人手的检测程序,下一步基于检测程 ...

  9. 插入DLL和挂接API——Windows核心编程学习手札之二十二

    插入DLL和挂接API --Windows核心编程学习手札之二十二 如下情况,可能要打破进程的界限,访问另一个进程的地址空间: 1)为另一个进程创建的窗口建立子类时: 2)需要调试帮助时,如需要确定另 ...

  10. 线程本地存储器——Windows核心编程学习手札之二十一

    线程本地存储器 --Windows核心编程学习手札之二十一 C/C++运行期库使用线程本地存储器,运行期库是在多线程应用程序出现前设计的,因此运行期库里的大多数函数是用于单线程应用程序的.函数strt ...

最新文章

  1. 不知道这些肯定没学过Go语言
  2. 暴风影音去广告链接和后台运行进程
  3. SQL中declare申明变量
  4. 逆向分析使用COM组件对象模型的代码
  5. snmp协议_软件评测师写作专栏之OSI七层模型及其常见的协议11
  6. [JEEWX问题修复] JeeWX开源版2.3几处代码修改。
  7. 视频盒子APP视频播放源代码安卓+IOS双端源码
  8. java迭代是引用_在迭代递归结构时无法获得可变引用:不能一次多次借用可变引用...
  9. sharepoint小 tip
  10. 《白帽子讲web安全》学习笔记 (4)
  11. jquery.form 异步校验_利用jQuery.validate异步验证用户名是否存在
  12. 如何建立网页快捷方式linux,怎么创建linux命令”快捷方式”或”自定义命令”...
  13. 见过最牛的GIF图片。
  14. 【NDSS 2021】On the Insecurity of SMS One-Time Password Messages against Local Attackers 论文笔记
  15. 总结SlickEdit的快捷键,分享当前自用配置
  16. cs用服务器运行,如何搭建自己的CS服务器(插件配置篇)
  17. Ceph新建monitor或者osd报错:use --overwrite-conf to overwrite
  18. 解决PHP提示Warning: Division by zero in错误
  19. MySql重装出错, Staring the server出错,日志3306 with user root with no password...
  20. Tomcat+Apache动静分离

热门文章

  1. Dennis Ritchie, father of Unix and C, dies
  2. 浅谈FMA与SMA(test)
  3. ElasticSearch 5学习(2)——Kibana+X-Pack介绍使用(全)
  4. php分页查询·······类
  5. 孪生素数问题--nyoj26
  6. 使用Eclipse创建的第一个javabean,cannot resolved to a type
  7. 模块化分析设计(简单的注册登录模块)
  8. 配置VS2008来Debug .Net框架源码
  9. 成熟有家男人与24岁女孩的精彩对白[推荐]
  10. 似懂非懂的Comparable与Comparator