• Functional Programming in Java venkat(13) Working with Resources


    Functional Programming in Java venkat(13): Working with Resources

    这里是记录学习这本书 Functional Programming in Java: Harnessing the Power Of Java 8 Lambda Expressions 的读书笔记,如有侵权,请联系删除。

    Managing Locks

    并发编程中锁很重要。

    synchronize的弊端

    首先,对synchronized的调用很难超时,这会增加死锁和活锁的机会。

    其次,很难模拟出synchronized,这使得单元测试很难看到代码是否遵守了适当的线程安全性。

    First, it’s
    hard to time out a call to synchronized, and this can increase the chance of
    deadlocks and livelocks. Second, it’s hard to mock out synchronized, and that
    makes it really hard to unit-test to see if code adheres to proper thread safety

    为了解决这些问题,在Java 5中引入了Lock接口,以及一些实现,如ReentrantLock。Lock接口给了我们更好的锁定、解锁控制权,检查是否有锁,如果在一定的时间范围内没有获得锁,还可以轻松地超时展示出来。因为这是一个接口,很容易模拟它的实现用于单元测试。

    To address these concerns, the Lock interface, along with a few implementations such as ReentrantLock, was introduced in Java 5. The Lock interface gives us better control to lock, unlock, check if a lock is available, and easily time out if a lock is not gained within a certain time span. Because this is an interface, it’s easy to mock up its implementation for the sake of unit testing

    Lock的弊端,需要显式的unlock

    There’s one caveat to the Lock interface—unlike its counterpart synchronized, it
    requires explicit locking and unlocking. This means we have to remember to
    unlock, and to do the same in the finally block. From our discussions so far
    in this chapter, we can see lambda expressions and the execute around method
    pattern helping out quite a bit here.

    看一个显式使用lock的例子,需要在finally块中unlock

    public class Locking {
      Lock lock = new ReentrantLock(); //or mock
      
      protected void setLock(final Lock mock) {
        lock = mock;
      } 
    
      public void doOp1() {
        lock.lock();
        try {
          //...critical code...
        } finally {
          lock.unlock();
        }
      }
      //...
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    使用lambda表达式来简化lock的调用,我们把复杂的部分放在一个方法runLocked中,使得调用的方法接口更简洁。

    package fpij;
    
    import java.util.concurrent.locks.Lock;
    
    public class Locker {
      public static void runLocked(Lock lock, Runnable block) {
        lock.lock();
    	
        try {
          block.run();
        } finally {
          lock.unlock();
        }    
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    lambda表达式调用runLock方法

    
      public void doOp2() {
        runLocked(lock, () -> {/*...critical code ... */});
      }
      
      public void doOp3() {
        runLocked(lock, () -> {/*...critical code ... */});
      }
      
      public void doOp4() {
        runLocked(lock, () -> {/*...critical code ... */});
      }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    python学习--特殊方法和属性
    LeetCode 1765 Map of Highest Peak (多源点BFS 推荐)
    打开 druid 监控报错Sorry, you are not permitted to view this page.
    Biotin-PEG4-IC(TFP ester/amine/NHS Ester/azide)特性分享
    腾讯汤道生:大模型只是起点,产业落地是AI更大的应用场景
    2.1.1+2.1.3进程的概念、组成、特征
    分组密码的模式
    一个匹配html标签的正则表达式
    搜索技术【广度优先搜索】 - 优先队列式广度优先搜索
    你已经应用了哪种服务注册和发现的模式呢?
  • 原文地址:https://blog.csdn.net/shizheng_Li/article/details/128104832