Guava的com.google.util.concurrent类库提供了相对于jdk java.util.concurrent包更加方便实用的并发类,Monitor类就是其中一个。Monitor类在处理互斥操作,同步访问数据块,提供了相比于synchronized关键字更加方便简洁的解决方案。

Synchronizing threads

Java提供了synchronized关键字来完成顺序访问某一数据块,但是使用synchronized存在一些问题,第一:如果我们使用在线程中使用wait(),我们必须记着使用while循环:

while (some condition) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

第二:如果包含多个condition可以导致一个wait状态,我们必须使用notifyAll,因为我们无法去指定的notify某个condition。使用notifyAll不尽人意,因为我们不得不去为了lock某个条件而唤醒所有的线程。Java 5引入了ReentrantLock,允许用户创建condition,可以通过使用Condition.signal()方法唤醒某一指定的condition,但是Condition.signalAll和notifyAll具有相同问题。也依然会存在while循环:

while (some condition) {
try {
condition.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

Monitor

Monitor类允许多个conditions,可以提供隐式的线程condition转换策略。下面是一个Monitor简单的例子:

public class SerialPrinterUsingGuava {
private static final int MAX_SIZE = 10;
private List<String> list = new ArrayList<String>();
private Monitor monitor = new Monitor(); private Guard listBelowCapacity = new Guard(monitor) {
@Override
public boolean isSatisfied() {
return list.size() < MAX_SIZE;
}
}; public void addToList(String item) throws InterruptedException {
monitor.enterWhen(listBelowCapacity);
try {
list.add(item);
} finally {
monitor.leave();
}
}
}

上面的例子中,当调用addToList方法向list中插入数据,进入monitor块,如果满足当前定义的限制条件,list.size<MaxSize,则执行list添加数据操作,最后在finally块中会释放当前线程占有的锁。monitor.enterwhen()方法的内部实际上使用是可重入锁,当定义的Guard条件满足时,整个Monitor块会被lock,在同一个时间只允许一个线程访问monitor代码块。

Monitor最佳实践

对于Monitor方法返回Boolean值,可以使用下面的代码模板,在If中包裹try-finally,在finally中释放锁。

if(monitor.enterIf(guardCondition){
try {
doWork();
} finally {
monitor.leave();
}
}

对于Monitor方法无返回值的,可以使用try-finally block,在finally中释放锁

monitor.enterWhen(guardCondition);
try {
doWork();
} finally {
monitor.leave()
}

Conclusion

今天和分享了Guava Monitor的一些特性,及其使用方法,更多的使用特性读者可以参考Google提供的Guava API文档自行查阅。

Guava monitor的更多相关文章

  1. Google guava 中的Monitor

    synchronized 自从Java提供了多线程编程,我们经常需要处理这样的情况:在特定的时间,我们需要限制访问,确保只有一个线程访问我们的代码.Java提供了同步关键字synchronized来实 ...

  2. guava学习--monitor

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

  3. Guava Cache相关

    官方:http://ifeve.com/google-guava-cachesexplained/ 理解:https://segmentfault.com/a/1190000007300118 项目中 ...

  4. Guava ---- Concurrent并发

    Guava在JDK1.5的基础上, 对并发包进行扩展. 有一些是易用性的扩展(如Monitor). 有一些是功能的完好(如ListenableFuture). 再加上一些函数式编程的特性, 使并发包的 ...

  5. Spring cache简单使用guava cache

    Spring cache简单使用 前言 spring有一套和各种缓存的集成方式.类似于sl4j,你可以选择log框架实现,也一样可以实现缓存实现,比如ehcache,guava cache. [TOC ...

  6. C#各种同步方法 lock, Monitor,Mutex, Semaphore, Interlocked, ReaderWriterLock,AutoResetEvent, ManualResetEvent

    看下组织结构: System.Object System.MarshalByRefObject System.Threading.WaitHandle System.Threading.Mutex S ...

  7. Guava库介绍之实用工具类

    作者:Jack47 转载请保留作者和原文出处 欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 本文是我写的Google开源的Java编程库Guava系列之一,主要介 ...

  8. Google Java编程库Guava介绍

    本系列想介绍下Java下开源的优秀编程库--Guava[ˈgwɑːvə].它包含了Google在Java项目中使用一些核心库,包含集合(Collections),缓存(Caching),并发编程库(C ...

  9. API Monitor简介(API监控工具)

    API Monitor是一个免费软件,可以让你监视和控制应用程序和服务,取得了API调用. 它是一个强大的工具,看到的应用程序和服务是如何工作的,或跟踪,你在自己的应用程序的问题. 64位支持 API ...

随机推荐

  1. rman恢复报ORA-27039

    查看资源限制: AIX修改参数文件/etc/security/limits 如下: 重新su到用户下即可生效

  2. redis数据类型及使用场景

    Redis数据类型  String: Strings 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字. 常用命令:  set,get,decr,incr,mge ...

  3. 使用base.调用父类里面的属性

    使用base.调用父类里面的属性public class parent { public string a; }public class child :parent { public string g ...

  4. cocos2d-x 从win32到android移植的全套解决方案

    引言:我们使用cocos2d-x引擎制作了一款飞行射击游戏,其中创新性地融入了手势识别功能.但是我们在移植过程中遇到了很多的问题,同时也发现网上的资料少而不全.所以在项目行将结束的时候,我们特地写了这 ...

  5. Swift -字符串

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #4dbf56 } p.p2 { margin: 0.0px 0. ...

  6. 什么是Angularjs

    AngularJs(后面就简称ng了)是一个用于设计动态web应用的结构框架.首先,它是一个框架,不是类库,是像EXT一样提供一整套方案用于设计web应用.它不仅仅是一个javascript框架,因为 ...

  7. "不能在 DropDownList 中选择多个项。"其解决办法及补充

    探讨C#.NET下DropDownList的一个有趣的bug及其解决办法 摘要: 本文就C#.Net 环境下Web开发中经常使用的DropDownList控件的SelectedIndex属性进行了详细 ...

  8. 【MongoDB初识】-其他操作

    又发现一种查询写法$wheredb.class.find({$}}) 排重db.class.distinct("stuCount") 一.MapReduce(摘录MongoDB实战 ...

  9. XV Open Cup named after E.V. Pankratiev. GP of Tatarstan

    A. Survival Route 留坑. B. Dispersed parentheses $f[i][j][k]$表示长度为$i$,未匹配的左括号数为$j$,最多的未匹配左括号数为$k$的方案数. ...

  10. Curator 异步获取结果

    原声的ZooKeeper 的CRUD API有同步和异步之分,对于异步API,需要传递AsyncCallback回调.对于getData,getChildren,exists这三个API,还可以设置W ...