• Guava monitor


    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文档自行查阅。

  • 相关阅读:
    【解题报告】 洛谷P1663 山
    【解题报告】 洛谷P6733 间歇泉
    【解题报告】 洛谷P1542 包裹快递
    二分总结
    SmartSchool CC校友录V8(毕业入世版)
    Hide/Show running Console
    Calculate drive total/free/available space
    C# list installed softwares
    How to: Modify a Project System So That Projects Load in Multiple Versions of Visual Studio
    PS:WINRAR制作32位安装程序和64位安装程序选项
  • 原文地址:https://www.cnblogs.com/jun-ma/p/4872786.html
Copyright © 2020-2023  润新知