java lambda使用_使用Java 8和Lambda简化ReadWriteLock

java lambda使用

考虑到旧版Java代码,无论您在哪里看,带有lambda表达式的Java 8绝对可以提高质量和可读性。 今天,让我们看一下ReadWriteLock以及如何使它使用起来更简单。 假设我们有一个称为Buffer的类,它可以记住队列中的最后几条消息,对旧消息进行计数并丢弃。 实现非常简单:

public class Buffer {private final int capacity;private final Deque<String> recent;private int discarded;public Buffer(int capacity) {this.capacity = capacity;this.recent = new ArrayDeque<>(capacity);}public void putItem(String item) {while (recent.size() >= capacity) {recent.removeFirst();++discarded;}recent.addLast(item);}public List<String> getRecent() {final ArrayList<String> result = new ArrayList<>();result.addAll(recent);return result;}public int getDiscardedCount() {return discarded;}public int getTotal() {return discarded + recent.size();}public void flush() {discarded += recent.size();recent.clear();}}

现在我们可以putItem() ,但是内部recent队列将仅保留最后一个capacity元素。 但是,它也记住必须丢弃多少项以避免内存泄漏。 该类工作正常,但仅在单线程环境中有效。 我们使用不是线程安全的ArrayDeque和非同步的int 。 尽管对int读写是原子的,但不能保证更改在不同线程中可见。 同样,即使我们将线程安全的BlockingDequeAtomicInteger一起使用,我们仍然处于竞争状态的危险中,因为这两个变量彼此不同步。

一种方法是synchronize所有方法 ,但这似乎很严格。 此外,我们怀疑读取的数量大大超过写入的数量。 在这种情况下, ReadWriteLock是一个很好的选择。 它实际上包括两个锁-一个用于读取,一个用于写入。 实际上,它们都为同一把锁竞争,而同一把锁可以同时由一个作者或多个读者获得。 因此,当没有人在写并且只有写者偶尔阻塞所有读者时,我们可以进行并发读取。 使用synchronized将始终阻止所有其他对象,无论他们做什么。 ReadWriteLock的可悲部分是它引入了许多样板。 您必须显式打开一个锁,并记住在finally块中对其进行unlock() 。 我们的实现变得难以阅读:

public class Buffer {private final int capacity;private final Deque<String> recent;private int discarded;private final Lock readLock;private final Lock writeLock;public Buffer(int capacity) {this.capacity = capacity;recent = new ArrayDeque<>(capacity);final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();readLock = rwLock.readLock();writeLock = rwLock.writeLock();}public void putItem(String item) {writeLock.lock();try {while (recent.size() >= capacity) {recent.removeFirst();++discarded;}recent.addLast(item);} finally {writeLock.unlock();}}public List<String> getRecent() {readLock.lock();try {final ArrayList<String> result = new ArrayList<>();result.addAll(recent);return result;} finally {readLock.unlock();
}public int getDiscardedCount() {readLock.lock();try {return discarded;} finally {readLock.unlock();}}public int getTotal() {readLock.lock();try {return discarded + recent.size();} finally {readLock.unlock();}}public void flush() {writeLock.lock();try {discarded += recent.size();recent.clear();} finally {writeLock.unlock();}}}

这是在8月8日之前完成的方式。有效,安全且丑陋。 但是,使用lambda表达式,我们可以将横切关注点包装在这样的实用工具类中:

public class FunctionalReadWriteLock {private final Lock readLock;private final Lock writeLock;public FunctionalReadWriteLock() {this(new ReentrantReadWriteLock());}public FunctionalReadWriteLock(ReadWriteLock lock) {readLock = lock.readLock();writeLock = lock.writeLock();}public <T> T read(Supplier<T> block) {readLock.lock();try {return block.get();} finally {readLock.unlock();}}public void read(Runnable block) {readLock.lock();try {block.run();} finally {readLock.unlock();}}public <T> T write(Supplier<T> block) {writeLock.lock();try {return block.get();} finally {writeLock.unlock();}
public void write(Runnable block) {writeLock.lock();try {block.run();} finally {writeLock.unlock();}}}

如您所见,我们包装了ReadWriteLock并提供了一组可使用的实用程序方法。 原则上,我们希望传递一个RunnableSupplier<T> (具有单个T get()方法的接口),并确保调用它时已被适当的锁包围。 我们可以编写完全相同的包装器类,而无需使用lambda,但是使用它们可以大大简化客户端代码:

public class Buffer {private final int capacity;private final Deque<String> recent;private int discarded;private final FunctionalReadWriteLock guard;public Buffer(int capacity) {this.capacity = capacity;recent = new ArrayDeque<>(capacity);guard = new FunctionalReadWriteLock();}public void putItem(String item) {guard.write(() -> {while (recent.size() >= capacity) {recent.removeFirst();++discarded;}recent.addLast(item);});}public List<String> getRecent() {return guard.read(() -> {return recent.stream().collect(toList());});}public int getDiscardedCount() {return guard.read(() -> discarded);}public int getTotal() {return guard.read(() -> discarded + recent.size());}public void flush() {guard.write(() -> {discarded += recent.size();recent.clear();});}}

看看我们如何调用guard.read()guard.write()传递应该受到保护的代码段? 看起来很整洁。 顺便说一句,您是否注意到我们如何使用stream()将任何集合转换为任何其他集合(在这里: Deque into List stream() ? 现在,如果我们提取几个内部方法,则可以使用方法引用来进一步简化lambda:

public void flush() {guard.write(this::unsafeFlush);
}private void unsafeFlush() {discarded += recent.size();recent.clear();
}public List<String> getRecent() {return guard.read(this::defensiveCopyOfRecent);
}private List<String> defensiveCopyOfRecent() {return recent.stream().collect(toList());
}

这只是利用lambda表达式来改进现有代码和库的众多方法之一。 我们真的很高兴他们终于进入Java语言了,同时已经出现在其他数十种JVM语言中。

翻译自: https://www.javacodegeeks.com/2014/03/simplifying-readwritelock-with-java-8-and-lambdas.html

java lambda使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/342048.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【渝粤教育】国家开放大学2018年秋季 0692-22T化工设备机械基础 参考试题

试卷代码&#xff1a;0699 2018-2019学年第1学期期末考试 阅读与写作 (闭卷) 2019年1月 一、阅读以下文章&#xff0c;并回答问题。&#xff08;共40分&#xff09; 雁南飞 胡 同 ①春天来了&#xff0c;小燕子乘着南风伴着细雨再一次回到了北方的那个屋檐下。看着它们忙忙碌…

光端机常见问题介绍

光端机在视频监控中的应用可以说是非常广泛&#xff0c;但是我们在调试安装的过程当中常常容易出现三类问题&#xff1a;一、电信号不能正常接收&#xff1b;二、电源正常但是不能正常工作&#xff1b;三、视频正常但反向数据有问题。接下来就由飞畅科技的小编来为大家详细介绍…

【渝粤教育】国家开放大学2018年秋季 1126t社会医学 参考试题

试卷代号&#xff1a;1134 行政管理学&#xff08;本&#xff09; 试题答案及评分标准 &#xff08;供参考&#xff09; 2019年1月 一、单项选择题&#xff08;每小题1分&#xff0c;共10分&#xff0c;每小题只有一项答案正确&#xff0c;请将正确答案的序号填在括号内&#x…

节点式光端机与点对点式光端机的区别

对光端机这块了解的朋友应该都知道&#xff0c;以前老式的光端机是有分点对点式光端机与节点式光端机的。而现在光端机&#xff0c;可组成SDH环网、星形网、树形网、点对点、点对多点等多种组网方式。接下来飞畅科技就来为大家详细介绍下节点光端机与点对点光端机之间的区别&am…

【渝粤教育】国家开放大学2018年秋季 1344T金融风险管理 参考试题

科目编号&#xff1a;1358 座位号 2018-2019学年度第一学期期末考试 民族理论与民族政策 试题 2019年 1月 填空题&#xff08;每空2分&#xff0c;共16分&#xff09; 1.一般来说&#xff0c;民族在历史渊源、生产方式、语言、文化、、方面具有共同的特征。 2.现阶段民族工作…

【渝粤教育】国家开放大学2018年秋季 2196T社会调查研究与方法 参考试题

试卷代号&#xff1a;2219 房屋构造与维护管理 试题&#xff08;开卷&#xff09; 2019年1月 一、选择题&#xff08;20题&#xff0c;每题3分&#xff0c;共60分&#xff09; 1&#xff0e;如下图所示&#xff0c;形体的W面投影是( )。 2&#xff0e;关于剖面图和断面图&…

关于模拟量转光纤的不同实现方法与区别

模拟量/光纤转换器是杭州飞畅科技专门为解决复杂电磁环境下的模拟量信号传输而设计的一款工业级光纤通信传输设备。使用该设备可有效解决复杂电磁环境下&#xff08;如大量使用变频器、变压器、整流器等非线性设备的工业现场&#xff09;电磁干扰、地环干扰和雷电破坏等EMI导致…

Java Enterprise软件与应有的软件

许多开发人员在其职业生涯的某个阶段最终进入了Java“企业”世界。 我知道这个词会引起各种React&#xff0c;这是正确的。 通常&#xff0c;存在许多有趣的技术挑战的环境最终会成为那些没人愿意从事的环境&#xff0c;因为它们脆弱&#xff0c;难以处理且没有乐趣。 大型项目…

【渝粤教育】国家开放大学2018年秋季 3819-21T燃气安全管理 参考试题

试卷代号&#xff1a;3922 汽车运用基础 试题答案及评分标准 &#xff08;供参考&#xff09; 2019年1月 一、单项选择题&#xff08;下列各题的备选答案中&#xff0c;只有一个选项是正确的&#xff0c;请把正确答案的序号填写在括号内。15小题&#xff0c;每小题2分&#xf…

模拟视频光端机与数字光端机究竟有何区别

模拟光端机采用了PFM调制技术实时传输图象信号&#xff0c;发射端将模拟视频信号先进行PFM调制后&#xff0c;再进行电-光转换&#xff0c;光信号传到接收端后&#xff0c;进行光电转换&#xff0c;然后进行PFM解调&#xff0c;恢复出视频信号。数字光端机是一种通过数字电路控…

【渝粤教育】国家开放大学2018年秋季 8184-21T (1)护理伦理学 参考试题

编号&#xff1a;8634 18-19学年第1学期期末考试 Android智能手机编程 试题&#xff08;开卷&#xff09; 一、选择题&#xff1a;&#xff08;每题4分&#xff0c;共40分&#xff09; 1.在Android应用中需要添加访问互联网的权限配置&#xff08;Permission&#xff09;&…

什么叫光端机?视频光端机的分类具体有哪些?

什么叫光端机&#xff1f;光端机顾名思义就是光信号传输的终端设备&#xff0c;是一个延长数据传输的光纤通信设备&#xff0c;它主要是通过信号调制、光电转化等技术&#xff0c;利用光传输特性来达到远程传输的目的。 视频光端机的分类&#xff1a; 视频光端机在中国的发展是…

【渝粤教育】国家开放大学2019年春季 0505-22T护理学基础 参考试题

编号&#xff1a;0505 座位号 2018&#xff5e;2019学年度第二学期期末考试 护理学基础试题 2019年6月 一、名词解释&#xff08;每题5分&#xff0c;共20分&#xff09; 沟通 护理诊断 尿失禁 自体输血 二、填空 &#xff08;每空2分&#xff0c;共30分&#xff09; 1&a…

【渝粤教育】国家开放大学2019年春季 1025保险学概论 参考试题

试卷代号&#xff1a;1025 2019年春季学期期末统一考试 保险学概论试题 2019年7月 注意事项 一、将你的学号、姓名及分校&#xff08;工作站&#xff09;名称填写在答题纸的规定栏内。考试结束后&#xff0c;把试卷和答题纸放在桌上。试卷和答题纸均不得带出考场。监考人收完考…

什么是3G-SDI光端机?

3G-SDI光端机设计和生产是适合于电视行业的高可靠、高性能的串行数字光传输设备&#xff0c;满足DVB回传和制作&#xff0c;现场制作&#xff0c;DVB-ASI传输,新闻采集&#xff0c;现场直播信号传输&#xff0c;远程演播室&#xff0c;通用数字视频传输业务&#xff0c;电信信号…

【渝粤教育】国家开放大学2019年春季 1171科学与技术 参考试题

试卷代号&#xff1a;1171 2019年春季学期期末统一考试 科学与技术试题&#xff08;开卷&#xff09; 2019年7月 一、选择题&#xff08;每题2分&#xff0c;共10分&#xff09; 1.自然界中一切物体的相互作用&#xff0c;都可以归结为四种基本的相互作用&#xff0c;即引力、弱…

【渝粤教育】国家开放大学2019年春季 133大学物理 参考试题

科目编号&#xff1a;0133 座位号 2018-2019学年度第二学期期末考试 大学物理 试题 2019年 7 月 单选题&#xff08;本大题共5小题&#xff0c;每小题4分&#xff0c;共计20分&#xff09; 静电场的高斯定理表明&#xff0c;静电场是 。 A. 有源场 B. 无源场 C. 保守力场 D. …

如何判断是不是真正的物理隔离网络光端机

现如今&#xff0c;随着各种通信技术的发展&#xff0c;光端机在各个领域应用非常广泛&#xff0c;尤其是在电力、银行、公安、部队、铁路、大型企事业单位专网这一块对物理隔离的以太网接入需求很大。虽然国内的光端机厂家很多&#xff0c;有很多厂家名义上说自家的是物理隔离…

weblogic中数据源_如何在WebLogic Server中创建MySQL数据源

weblogic中数据源使用应用程序服务器的一件很酷的事情是&#xff0c;它允许您在应用程序外部创建DataSource&#xff0c;并且可以与线程池和事务管理器等一起管理它。对于WebLogic Server&#xff0c;它附带了许多内置的JDBC驱动程序&#xff0c;例如Oracle数据库和MySQL等随时…

【渝粤教育】国家开放大学2019年春季 2175市场营销学 参考试题

试卷代号&#xff1a;2175 2 0 1 9年春季学期期末统一考试 市场营销学 试题 注意事项 2019年7月 一、将你的学号、姓名及分校&#xff08;工作站&#xff09;名称填写在答题纸的规定栏内。考试结束后&#xff0c;把试卷和答题纸放在桌上。试卷和答题纸均不得带出考场。监考人收…