- 浏览: 604558 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (300)
- Web前端 (27)
- Java疑难 (60)
- 面试 (59)
- 汇编语言 (1)
- 计算机组成原理 (2)
- 操作系统 (3)
- 计算机网络 (6)
- C/C++疑难 (9)
- SSH (2)
- Web开发 (15)
- 故障 (3)
- 软件开发 (16)
- Portal开发 (1)
- 后台开发 (6)
- 数据库 (35)
- 设计模式 (4)
- 数据结构与算法 (4)
- Linux (3)
- 项目管理 (10)
- 多线程 (12)
- 嵌入式 (9)
- 网络编程 (4)
- 架构设计 (20)
- 软件工具技巧 (7)
- 并行并发 (4)
- 窗口编程 (7)
- 串口编程 (0)
- Flex (2)
- 协议 (1)
- 通讯方式 (4)
- 性能分析优化 (5)
- 测试相关 (4)
- 海量数据处理 (2)
- JAVA核心技术 (10)
- SOA (3)
- 攻略规划 (1)
- 爬虫/搜索 (2)
- 正则表达式 (1)
- A Comparison Of NoSQL Database Management Systems And Models (1)
最新评论
-
charles751:
分析的很好!但有一点:只要同步组合操作就可以了,不一定非要sy ...
Vector 是线程安全的? -
S346618898:
core Java中有一段:Vector类对自己的所有可修改方 ...
Vector 是线程安全的? -
code_cj:
基本上明白了.但执行顺是否应该是/etc/profile -& ...
profile bashrc bash_profile之间的区别和联系 -
xd2008ck:
各自有各自的场景吧楼主不要太激进了
Vector 是线程安全的? -
zwt2001267:
写的不错,赞一个
Vector 是线程安全的?
当 Java 运行时知识库提供便利、预置的并发性时,为什么还要苦苦挣扎,试图将并发性导入到您的 Collections 类?本系列的下一篇文章将会进一步探讨 java.util.concurrent 名称空间的内容。
Concurrent Collections 是 Java™ 5 的巨大附加产品,但是在关于注释和泛型的争执中很多 Java 开发人员忽视了它们。此外(或者更老实地说),许多开发人员避免使用这个数据包,因为他们认为它一定很复杂,就像它所要解决的问题一样。
事实上,java.util.concurrent 包含许多类,能够有效解决普通的并发问题,无需复杂工序。阅读本文,了解 java.util.concurrent 类,比如 CopyOnWriteArrayList 和 BlockingQueue 如何帮助您解决多线程编程的棘手问题。
1. TimeUnit
尽管本质上 不是 Collections 类,但 java.util.concurrent.TimeUnit 枚举让代码更易读懂。使用 TimeUnit 将使用您的方法或 API 的开发人员从毫秒的 “暴政” 中解放出来。
TimeUnit 包括所有时间单位,从 MILLISECONDS 和 MICROSECONDS 到 DAYS 和 HOURS,这就意味着它能够处理一个开发人员所需的几乎所有的时间范围类型。同时,因为在列举上声明了转换方法,在时间加快时,将 HOURS 转换回 MILLISECONDS 甚至变得更容易。
2. CopyOnWriteArrayList
创建 数组的全新副本是过于昂贵的操作,无论是从时间上,还是从内存开销上,因此在通常使用中很少考虑;开发人员往往求助于使用同步的 ArrayList。然而,这也是一个成本较高的选择,因为每当您跨集合内容进行迭代时,您就不得不同步所有操作,包括读和写,以此保证一致性。
这又让成本结构回到这样一个场景:需多读者都在读取 ArrayList,但是几乎没人会去修改它。
CopyOnWriteArrayList 是个巧妙的小宝贝,能解决这一问题。它的 Javadoc 将 CopyOnWriteArrayList 定义为一个 “ArrayList 的线程安全变体,在这个变体中所有易变操作(添加,设置等)可以通过复制全新的数组来实现”。
集合从内部将它的内容复制到一个没有修改的新数组,这样读者访问数组内容时就不会产生同步成本(因为他们从来不是在易变数据上操作)。
本质上讲,CopyOnWriteArrayList 很适合处理 ArrayList 经常让我们失败的这种场景:读取频繁,但很少有写操作的集合,例如 JavaBean 事件的 Listeners。
3. BlockingQueue
BlockingQueue 接口表示它是一个 Queue,意思是它的项以先入先出(FIFO)顺序存储。在特定顺序插入的项以相同的顺序检索 — 但是需要附加保证,从空队列检索一个项的任何尝试都会阻塞调用线程,直到这个项准备好被检索。同理,想要将一个项插入到满队列的尝试也会导致阻塞调用线 程,直到队列的存储空间可用。
BlockingQueue 干净利落地解决了如何将一个线程收集的项“传递”给另一线程用于处理的问题,无需考虑同步问题。Java Tutorial 的 Guarded Blocks 试用版就是一个很好的例子。它构建一个单插槽绑定的缓存,当新的项可用,而且插槽也准备好接受新的项时,使用手动同步和 wait()/notifyAll() 在线程之间发信。(详见 Guarded Blocks 实现。)
尽管 Guarded Blocks 教程中的代码有效,但是它耗时久,混乱,而且也并非完全直观。退回到 Java 平台较早的时候,没错,Java 开发人员不得不纠缠于这种代码;但现在是 2010 年 — 情况难道没有改善?
清单 1 显示了 Guarded Blocks 代码的重写版,其中我使用了一个 ArrayBlockingQueue,而不是手写的 Drop。
清单 1. BlockingQueue
import java.util.
*
;
import java.util.concurrent.
*
;
class Producer
implements Runnable
{
private
BlockingQueue
<
String
>
drop;
List
<
String
>
messages
=
Arrays.asList(
"
Mares eat oats
"
,
"
Does eat oats
"
,
"
Little lambs eat ivy
"
,
"
Wouldn't you eat ivy too?
"
);
public
Producer(BlockingQueue
<
String
>
d) { this.drop
=
d; }
public
void run()
{
try
{
for
(
String
s : messages)
drop.put(s);
drop.put(
"
DONE
"
);
}
catch (InterruptedException intEx)
{
System.out.println(
"
Interrupted!
"
+
"
Last one out, turn out the lights!
"
);
}
}
}
class Consumer
implements Runnable
{
private
BlockingQueue
<
String
>
drop;
public
Consumer(BlockingQueue
<
String
>
d) { this.drop
=
d; }
public
void run()
{
try
{
String
msg
=
null
;
while
(!((msg
=
drop.take()).equals(
"
DONE
"
)))
System.out.println(msg);
}
catch (InterruptedException intEx)
{
System.out.println(
"
Interrupted!
"
+
"
Last one out, turn out the lights!
"
);
}
}
}
public
class ABQApp
{
public
static void main(
String
[] args)
{
BlockingQueue
<
String
>
drop
=
new
ArrayBlockingQueue(
1
,
true
);
(
new
Thread(
new
Producer(drop))).start();
(
new
Thread(
new
Consumer(drop))).start();
}
}
ArrayBlockingQueue 还体现了“公平” — 意思是它为读取器和编写器提供线程先入先出访问。这种替代方法是一个更有效,但又冒穷尽部分线程风险的政策。(即,允许一些读取器在其他读取器锁定时运行 效率更高,但是您可能会有读取器线程的流持续不断的风险,导致编写器无法进行工作。)
BlockingQueue 还支持接收时间参数的方法,时间参数表明线程在返回信号故障以插入或者检索有关项之前需要阻塞的时间。这么做会避免非绑定的等待,这对一个生产系统是致命的,因为一个非绑定的等待会很容易导致需要重启的系统挂起。
4. ConcurrentMap
Map 有一个微妙的并发 bug,这个 bug 将许多不知情的 Java 开发人员引入歧途。ConcurrentMap 是最容易的解决方案。
当一个 Map 被从多个线程访问时,通常使用 containsKey() 或者 get() 来查看给定键是否在存储键/值对之前出现。但是即使有一个同步的 Map,线程还是可以在这个过程中潜入,然后夺取对 Map 的控制权。问题是,在对 put() 的调用中,锁在 get() 开始时获取,然后在可以再次获取锁之前释放。它的结果是个竞争条件:这是两个线程之间的竞争,结果也会因谁先运行而不同。
如果两个线程 几乎同时调用一个方法,两者都会进行测试,调用 put,在处理中丢失第一线程的值。幸运的是,ConcurrentMap 接口支持许多附加方法,它们设计用于在一个锁下进行两个任务:putIfAbsent(),例如,首先进行测试,然后仅当键没有存储在 Map 中时进行 put。
实现代码看起来几乎相同,但是应用程序有额外获益:SynchronousQueue 允许在队列进行一个插入,只要有一个线程等着使用它。
在实践中,SynchronousQueue 类似于 Ada 和 CSP 等语言中可用的 “会合通道”。这些通道有时在其他环境中也称为 “连接”,这样的环境包括 .NET (见 参考资料)。
发表评论
-
file.encoding
2015-07-23 23:43 2524参考链接 http://blog. ... -
java常用工具
2015-03-30 17:05 788jpsjstatjstackjinfojmap -
后台线程(守护线程)
2014-04-09 23:42 1420所谓的后台线程,是指在程序运行的时候在后台提供一种通用服务的 ... -
Spring配置文件xsi:schemaLocation无法解析导致启动失败的解决方案
2014-03-27 16:59 3037来源http://www.jnan.org/archives ... -
Java 内存模型
2014-01-08 10:05 695Java 内存模型 转自WIKI,自由的百科全书 跳转到 ... -
抽象类与接口选择
2013-12-06 00:20 910从设计理念层面看 abst ... -
javac和java的路径问题
2013-11-03 22:57 5748javac和java的路径问题 ... -
Java调用dll的路径问题解决
2013-10-18 00:37 2737前言:一般我们在用java写jni类库的时候,总是得把生成的 ... -
Java Ant build.xml详解
2013-07-21 23:52 9631、什么是antant是构建 ... -
Java疑难点总结
2013-06-07 02:41 11111.类加载和初始化 加载——>连接(验证-> ... -
Java 虚拟机是如何判定两个 Java 类是相同
2013-05-27 17:17 1156Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的 ... -
java.lang.ClassNotFoundException和java.lang.NoClassDefFoundError的区别
2013-05-21 11:05 980这2个东西应该是java里很常见,很简单,他们都和clas ... -
深入探讨 Java 类加载器
2013-05-21 11:06 836参考 深入探讨 Java 类加载器 http://ww ... -
深入探讨 Java 类加载器
2013-05-20 15:51 813摘自http://www.ibm.com/develope ... -
深入探讨 Java 类加载器
2013-05-20 15:48 971<!--[if !mso]> <styl ... -
final变量需要显示初始化
2013-05-20 00:15 968final int f = 10;//final in ... -
try-catch-finally中return的执行情况
2013-05-18 12:04 1780public class -
Java远程通讯可选技术及原理
2013-05-13 11:13 976源自http://www.blogjava.net/Blue ... -
Java EJB、CORBA、Webservices分布式通信基本原理及特点
2013-05-13 10:19 15211. Java远程调用的特点是什么 2. Java ... -
java传参是传值还是传引用
2013-04-28 00:44 1373个人觉得java是传值,当参数类型是基本类型,复制的是值,而 ...
相关推荐
微信视频号大风口项目,多赛道选择,可矩阵,玩法简单轻松上手.mp4
电子科技大学图书馆微信小程序_中国电子科技大学
2023-04-06-项目笔记-第三百七十二阶段-课前小分享_小分享1.坚持提交gitee 小分享2.作业中提交代码 小分享3.写代码注意代码风格 4.3.1变量的使用 4.4变量的作用域与生命周期 4.4.1局部变量的作用域 4.4.2全局变量的作用域 4.4.2.1全局变量的作用域_1 4.4.2.370局变量的作用域_370- 2025-01-08
期末课设-Python和Django实现音乐推荐系统(含源码+课设报告+答辩PPT).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载
FlexiFed实验初学者学生复制品_ FlexiFed留级生.zip
sTM32 ADC采集滤波算法,卡尔曼 中位值 同步对比输出源程序,芯片采用STM32f103c8t6.算法采用卡尔曼滤波算法中位值滤波算法, 波形输出正常采集的卡尔曼 中位值三个波形输出,程序注释详细。
详细介绍及样例数据:https://blog.csdn.net/T0620514/article/details/145019667
三相两电平逆变器模型预测控制(MPC)simulink仿真,内有坐标变和MPC代码,可修改电流参考值,~~可用作电力电子方向入门学习
25混合A星算法路径规划Hybrid-Astar 以车辆的运动学模型为节点,以当前点到终点的Astar距离和RS距离两者最大的距离作为H(n)函数的估计代价,使用matlab实现(2016a以上版本)
考虑阶梯式碳交易机制与电制氢的综合能源系统热电优化 关键词:碳交易 电制氢 阶梯式碳交易 综合能源系统 热电优化 参考文档:《考虑阶梯式碳交易机制与电制氢的综合能源系统热电优化》基本复现 仿真平台:MATLAB+CPLEX 主要内容:代码主要做的是一个考虑阶梯式碳交易机制的电热综合能源系统优化调度研究,考虑综合能源系统参与碳交易市场,引入引入阶梯式碳交易机制引导IES控制碳排放,接着细化电转气(P2G)的两阶段运行过程,引入电解槽、甲烷反应器、氢燃料电池(HFC)替传统的P2G,研究氢能的多方面效益;最后提出热电比可调的热电联产、HFC运行策略,进一步提高IES的低碳性与经济性。 目标函数为以购能成本、碳排放成本、弃风成本最小,将原问题转化为混合整数线性问题,运用CPLEX商业求解器进行求解。
并离网逆变器仿真模型 逆变器PQ控制,Vf控制,无功能量发生器SVG,有源电力滤波器APF仿真模型
springboot176基于Spring Boot的装饰工程管理系统,含有完整的源码和报告文档
一、项目简介 本项目是一套基于SSM框架实现的生活缴费系统 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值 二、技术实现 jdk版本:1.8 及以上 ide工具:IDEA或者eclipse 数据库: mysql5.5及以上 后端:spring+springmvc+mybatis+maven+mysql 前端:vue,css,js 三、系统功能 系统角色主要包括:管理员、用户 系统主要功能包括: 用户登录 用户注册 首页 个人中心 修改密码 个人信息 用户管理 电表管理 电表缴费管理:查看缴费详情,缴费 ETC管理 ETC缴费管理 供暖管理 供暖缴费管理 固话管理 固话缴费管理 宽带管理 宽带缴费管理 燃气表管理 燃气表缴费管理 油卡管理 油卡缴费管理 水表管理 水表缴费管理 帮助中心类型管理 油卡所属公司管理 客服管理 轮播图管理等功能
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
多智能体、一致性、时滞 含通信时滞和输入时滞的多智能体一致性仿真 简单的多智能体一致性性仿真图,包含状态轨迹图和控制输入图。 适用于初学者。
内容概要:本文介绍了一种新的智能对比度增强技术——动态直方图均衡化(DHE)。该方法通过对输入图像的直方图进行分割并分别进行直方图均衡化来克服传统全局直方图均衡化(GHE)和其他方法存在的局限性,从而实现更好的图像细节保护及显著的整体对比度增强效果。具体来说,DHE基于局部极小值将图像直方图划分为子直方图,并重新调整各分区以避免高灰度频率部分对低频区域的影响。同时,在进行均衡时限制每种子直方图的灰度级范围,防止过度拉伸导致细节丢失等问题。 适用人群:从事计算机视觉和图像处理研究的专业人员,特别是关注对比度增强算法及其实际应用的研究学者和技术开发者。 使用场景及目标:可用于医疗影像处理、指纹识别等多个领域的前期预处理步骤;主要目的是改善低对比度图像的质量,提升后续图像识别或其他处理任务的效果。 其他说明:相比于现有技术如全球均值变换、局部直方图均衡以及特定直方图规格化等方式,本提出的DHE能有效避免因增强处理而引起的严重副作用如棋盘效应等,提供更加平滑自然的视觉体验。此外文中还展示了多个实验结果以验证新方法的有效性和优越性能表现。
我的超迷你机械臂机器人项目。_Dummy-Robot
实体单元椭圆主体扭转分析,着重分析扭矩的施加方式
OKR计划表 自我管理
用于微信小程序的ProtoBuffer库