- 浏览: 97768 次
- 性别:
- 来自: 深圳
文章分类
最新评论
4.1 集合包
ArrayList, LinkedList,Vector,TreeSet,HashMap,TreeMap 等,无需多说
4.2 并发包 (java.util.concurrent)
4.2.1 ConcurrentHashMap
线程安全的 HashMap 实现,主要原理是将集合分成多个段 ( 默认 16 个 ) ,分段加锁,实现高并发。
据作者的测试结果,在线程数较少时,无论元素数量多少, ConcurrentHashMap 带来的性能提升不明显,但在线程数为 50 以上时, ConcurrentHashMap 在增加和删除时性能提升了一倍左右,查找时性能提升了 10 倍左右。
因而,在并发场景, ConcurrentHashMap 较之 HashMap 是更好的选择
4.2.2 CopyOnWriteArrayList
线程安全的 ArrayList, 基于 ReentrantLock 保证增加元素和删除元素动作的互斥,在读操作时无锁。
据作者的测试结果,随着元素数量和线程数量增加, CopyOnWriteArrayList 在增加元素和删除元素时性能下降明显,比 ArrayList 更低。但在查找元素上却比 ArrayList 好很多(大于 10 倍)。
因此,在读多写少的并发场景, CopyOnWriteArrayList 较之 ArrayList 是更好的选择。
4.2.3 CopyOnWriteArraySet
基于 CopyOnWriteArrayList 实现,唯一不同的是每次 add 时调用的是 addIfAbsent 方法,此方法需遍历当前 Object 数组,检查待增加的元素是否已存在,已存在则直接返回。故性能略低于 CopyOnWriteArrayList
4.2.4 ArrayBlockingQueue
一个基于固定大小数组、 ReentrantLock 以及 Condition 实现的可阻塞的先进先出的 Queue.
类似的还有过 LinkedBlockingQueue, 对 put 和 offer 采用一把锁,对 take 和 poll 采用另一把锁,避免了读写时互相竞争锁的现象,因此,在高并发读写操作都多的情况下,性能会较 ArrayBlockingQueue 好很多
4.2.5 AtomicInteger
一个支持原子操作的 Integer 类,在没有 AtomicInteger 前,要实现一个按顺序获取的 ID ,就必须在每次获取时进行加锁操作,以避免出现并发时获取到同样 ID 的现象。借助 AtomicInteger ,则可以更简易地实现,如下:
Private static AtomicInteger counter = new AtomicInteger();
Public static int getNextId() {
Return counter.incrementAndGet();
}
incrementAndGet 方法基于 CPU 的 CAS 原语实现,基于 CAS 的操作可以认为是无阻塞的,因此性能好于同步锁的方式。
对于使用 JDK5 以上的版本时,应尽量使用 atomic 的类,除 AtomicInteger 外,还有 AtomicLong 、 AtomicBoolean 、 AtomicReference 等。
4.2.6 ThreadPoolExecutor
一个高效的、支持并发的线程池,要想用好这个线程池,需要合理配置 corePoolSize, 最大线程数、任务缓冲的队列,以及线程池满时的处理策略。常见的需要有如下两种
1. 高性能
如果希望高性能地执行 Runnable 任务,即当线程池中的线程数尚未达到最大个数,则立刻交给线程执行或在最大线程数量的保护下创建线程来执行,可选的方式为使用 SynchronousQueue 作为任务的队列。
2. 缓冲执行
如果希望 Runnable 任务尽量被 corePoolSize 范围的线程执行掉,可选的方式为使用 ArrayBlockingQueue 或 LinkedBlockQueue 作为任务缓冲的队列。这样,当线程数等于或超过 corePoolSize 后,会先加入缓冲队列中,而不是直接交由线程执行。
4.2.7 Executors
提供一些方便创建 ThreadPoolExecutor 的方式
1. newFixedThreadPool(int)
创建固定大小的线程池 keepAliveTime 为 0 ,即线程启动后就不退出,缓冲队列为 LinkedBlockingQueue, 大小为整型的最大数
2. newSingleThreadExecutor()
创建大小为 1 的固定线程池
3. newCachedThreadPool()
创建 corePoolSize 为 0 最大线程数为整型的最大数,线程 keepAliveTime 为 1 分钟,缓存任务的队列为 SynchronousQueue 的线程池
4. newSheduledThreadPool(ing)
创建 corePoolSize 为传入参数,最大线程数为整型的最大数,线程 keepAliveTime 为 0, 缓存任务的队列为 DelayedWorkQueue 的线程池。在实际业务中,通常会有一些需要定时或延迟执行的任务,更典型的是在异步操作时需要超时回调的场景。
JDK5 之前,用 Timer 实现这个功能,两者区别:
1. Timer 单线程,一旦一个 task 运行缓慢,其它的 task 也会推迟, ScheduledThreadPool 并发
2. Timer 中的 task 抛出 RunntimeException 时,其它 task 也不会执行
3. ScheduledThreadPool 可以执行 callable 的 task
4.2.8 FutureTask
可用于异步获取执行结果或取消执行任务的场景,通过传入 Runnable 或 Callable 的任务给 FutureTask ,直接调用其 run 方法或放入线程池执行,之后可在外部通过 FutureTask 的 get 异步获取执行结果。 FutureTask 可以确保即使调用了多闪 run 方法,它都会只执行一次 Runnable 或 Callable 任务。
4.2.9 Semaphore
用于控制某资源同时被访问的个数的类,例如连接池中控制创建的连接个数。
4.2.10 CountDownLatch
可用于控制多个线程同时开始某动作的类,采用的方式为减计数方式。当计数减至零时,位于 latch.await 后的代码才会被执行。
4.2.11 CyclicBarrier
和 CountDownLatch 不同, CyclicBarrier 是当 await 数量达到设定的数量后,才继续向下执行。
4.2.12 ReentrantLock
一个更为方便的控制并发资源的类,和 synchronized 语法达到的效果是一致的。这两者之间如何取舍呢,借用 Brian Goetz 的话 (http://www.ibm.com/developerworks/cn/java/j-jtp10264/index.html) :
答案非常简单
——
在确实需要一些
synchronized
所没有的特性的时候,比如时间锁等候、可中断锁等候、无块结构锁、多个条件变量或者锁投票。
ReentrantLock
还具有可伸缩性的好处,应当在高度争用的情况下使用它,但是请记住,大多数
synchronized
块几乎从来没有出现过争用,所以可以把高度争用放在一边。我建议用
synchronized
开发,直到确实证明
synchronized
不合适,而不要仅仅是假设如果使用
ReentrantLock
“
性能会更好
”
。请记住,这些是供高级用户使用的高级工具。(而且,真正的高级用户喜欢选择能够找到的最简单工具,直到他们认为简单的工具不适用为止。)。一如既往,首先要把事情做好,然后再考虑是不是有必要做得更快。
4.2.13 Condition
接口,典型实现 ReentrantLock , ReentrantLock 提供了一个 newCondition 方法,以便用户在同一个锁的情况下可以根据不同的情况执行等待或唤醒动作。
ReentrantLock.newCondition().await()
ReentrantLock..newCondition().signal()
4.2.14 RenentrantReadWriteLock
和 ReentrantLock 没有继承关系,它提供了读锁( ReadLock )和写锁( WriteLock ),比 ReentrantLock 的一把锁,读写锁分离对读多写少的情况,提高性能。
当调用读锁的 lock 方法时,没有线程持有写锁,就可获得读锁,意味着只要进行读操作,就没有其它线程进行写操作,读操作时无阻塞的;
当调用写锁的 lock 时,如果此时没有线程持有读锁或写锁,则可继续,意味着要进行写时,如果有其它线程进行读或写,就会被阻塞,
读写锁使用时的升级和降级机制:
同一线程中,持有读锁后,不能直接调用写锁的 lock
同一线程中,持有写锁后,可调用读锁的 lock 方法,之后如果调用写锁的 unlock 方法,那么当前锁将降级为读锁。
记作者的测试: 同时启动 102 个线程, 100 个进行读操作 (HashMap.get) , 2 个进行写操作 (HashMap.put), 较之 ReentrantLock , ReentrantReadWriteLock 性能提升了三倍多。
以上分析了 JDK5 以后版本提供的并发包中一些常用类的实现方法,这些类能够帮助开发者更好地控制高并发下的资源操作,尽可能地避免出现不一致及资源竞争激烈等现象。总的来说,基于 CAS 、拆分锁、 voliate 及 AbstractueuedSynchronier 是这些类的主要实现方法,这些方法都是为了尽量减少高并发时的竞争现象,对于实际编码有一定的参考价值,从而保障程序即使在 高并发时也能保持较高的性能。
发表评论
-
技术文章精华合集(持续更新中)
2016-09-20 19:09 780Kafka深度解析 分库分表系列文章 来自 ... -
<<More Joel on Software>> 如何扮演程序经理的角色
2011-07-03 15:13 827制作伟大软体的秘方之 ... -
<<More Joel on Software>> 利诱管理法
2011-07-03 15:10 1000利诱管理法 Joke: A poor J ... -
<<More Joel on Software>> The Joel Test: 软件开发成功 12 法则
2011-07-03 14:42 728作者: 周思博 (Joel Spols ... -
<<More Joel on Software>> 看起来简单, 实际上复杂
2011-07-03 14:41 789作者: 周思博 (Joel Spolsky) 译: Bo Y ... -
<<More Joel on Software>> 膨胀软件与80/20的谣传
2011-07-03 14:38 913作者: 周思博 (Joel Spols ... -
<<More Joel on Software>> 每日构建(daily build)是你的朋友
2011-07-03 14:37 894作者: 周思博 (Joel Spols ... -
<<More Joel on Software>> 五个为什么
2011-07-03 14:20 979五个为什么(译文) ... -
<<More Joel on Software>> 飙高音
2011-07-03 13:54 942飙高音(译文) 作者: 阮一峰 日期: 2009年 ... -
<<More Joel on Software>> 关于战略问题的通信之六
2011-07-03 13:51 798关于战略问题的通信之六(译文) 作者: 阮一峰 日 ... -
<<More Joel on Software>> 易用性是不够的
2011-07-03 13:41 775易用性是不够的(译文) 作者: 阮一峰 日期: 2 ... -
<<More Joel on Software>> 军事化管理法
2011-07-03 13:28 1009高科技公司能否采用军事化管理?(译文) 作者: 阮一峰 ... -
<<More Joel on Software>> 寻找优秀的程序员
2011-07-03 13:24 1234=================== 寻找 ... -
读书笔记:《分布式JAVA应用 基础与实践》 第七章 构建可伸缩的系统
2011-05-29 12:09 1140通常将通过升级或增加单机机器的硬件来支撑访问量及数据量增长的方 ... -
读书笔记:《分布式JAVA应用 基础与实践》 第六章 构建高可用的系统
2011-05-28 11:02 1236对于互联网或企业中的大型应用而言,多数要求做到 7*24 ... -
读书笔记:《分布式JAVA应用 基础与实践》 第五章 性能调优(二)
2011-05-22 21:34 11215.2 调优 找出性 ... -
读书笔记:《分布式JAVA应用 基础与实践》 第五章 性能调优(一)
2011-05-22 13:43 11585.1 寻找性能瓶颈 通常性能瓶颈的 ... -
读书笔记:《分布式JAVA应用 基础与实践》 第三章 3.3 JVM线程资源同步及交互机制(二)
2011-05-17 21:52 962接下来网上没有,貌似 ... -
《分布式JAVA应用 基础与实践》 第三章 3.3 JVM线程资源同步及交互机制(一)
2011-05-17 19:09 9193.3 JVM线程资源同步及交互机制 Java程序采用 ... -
《分布式JAVA应用 基础与实践》 第三章 3.2 JVM内存管理(四)
2011-05-17 19:00 9523.2.4 JVM内存状况查看 ...
相关推荐
1.2 Java的特点:Java语言具有平台无关性、面向对象、分布式处理、多线程支持、动态加载类库、安全性高、可移植性强等特点。 1.3 Java开发环境:Java开发环境包括Java Development Kit(JDK)、Integrated ...
【Java基础整理笔记超详细】 Java是一门广泛使用的高级编程语言,由Sun Microsystems(后被Oracle收购)在1995年推出。它的设计目标是跨平台、面向对象,并且具有健壮性和安全性。Java这个名字源于印度尼西亚的咖啡...
3. 分布式:Java 语言支持 Internet 应用程序的开发,具有很强的分布式特性。 4. 动态绑定:Java 语言全面支持动态绑定,而 C++ 语言只对虚函数使用动态绑定。 Java 语言的应用领域非常广泛,包括: 1. 个人计算机...
Java JDK(Java Development Kit)是Java编程语言的核心组件,包含Java运行环境、编译器、类库以及各种工具,是开发者进行Java程序开发的基础。Java JDK 6.0是Oracle公司发布的一个重要版本,提供了许多新的特性和...
- **分布式**:Java内置对网络的支持,方便开发分布式应用。 - **动态性**:Java具有良好的动态性,能够适应不断变化的环境。 - **多线程**:Java提供内置多线程支持,简化并发编程。 - **安全性**:Java具有...
毕向东的Java基础视频教程笔记为我们提供了一个学习Java基础知识的宝贵资源。在这个笔记中,我们主要讨论以下几个核心概念: 1. **Java平台的三个版本**: - Java SE (Standard Edition):适用于桌面应用程序和...
10. **JNDI与JMS**:Java Naming and Directory Interface(JNDI)用于查找和绑定分布式系统中的资源,Java Message Service(JMS)则是Java消息传递的标准。这两个技术在企业级应用中广泛使用。 通过这份Java JDK ...
JAVA 系统一般包含四个部分:JAVA 环境、JAVA 语言、JAVA API 应用程序接口、JAVA 类别库。JDK 是 JAVA Developer's Kit 的简称,意即 JAVA 的开发工具。JAVA 2 SDK 开发工具可从 SUN 公司网站下载,包含这四个部分...
JRE是运行Java应用程序所需的基本环境,由JVM(Java虚拟机)和核心类库组成。而JDK则在此基础上增加了开发工具,如编译器javac等。 安装JDK后,可以通过图形界面或命令行与系统交互。在Windows系统中,可以使用Win+...
- **JDK**(Java Development Kit):Java开发工具包,包括Java编译器、文档、示例代码和工具,以及JRE,是Java开发环境的基础。 - **JVM**(Java Virtual Machine):Java虚拟机,负责执行Java字节码,提供了一个...
1. **Java Development Kit (JDK)**:开发Java应用程序所需的工具集合,包括编译器(javac)、解释器(java)、jar打包工具等。 2. **Java Class Library**:提供大量预定义类和接口,如集合框架、I/O流、网络编程、...
- **起源与发展**:Java 最初由 Sun Microsystems 的 James Gosling 在 Green Project 中开发,初衷是为了创建一个名为 Star7 的应用程序。其命名灵感来源于 Gosling 办公室外的一棵橡树(Oak)。随着全球互联网的...
1. **JDK与SDK**:Java Development Kit (JDK) 是Java开发的基础,包含了编译器、JRE(Java Runtime Environment)以及一系列工具,如Javadoc和JAR。Software Development Kit (SDK) 是一个更广泛的术语,通常包括...
### 第四章:异常机制 - 异常处理机制:捕获、抛出、try-catch-finally语句。 - 自定义异常类的创建。 - 常用异常类:如`IOException`、`NullPointerException`等。 ### 第五章:多线程技术 - 线程的概念与特点。...
6. 分布式:Java提供了丰富的网络API,支持Internet应用开发,可以轻松实现分布式计算和数据共享。 7. 健壮性:Java的强类型检查、异常处理和垃圾回收机制增强了程序的稳定性和可靠性。 8. 高性能:虽然Java最初是...
- 分布式:Java提供内置的支持用于创建分布式应用。 - 动态性:Java支持运行时的类装载、动态链接等特性。 - 多线程:Java提供内置的多线程支持,方便开发复杂的并发程序。 - 安全性:Java具有强大的安全特性,...
- **分布式**:Java天生支持网络计算,易于实现客户端与服务器之间的通信。 - **动态性**:Java语言支持动态链接,即可以在运行时动态加载类库。 - **多线程**:Java内置了对多线程的支持,便于开发高并发应用。 ...
- **简单性**:Java设计者的目标之一是使它易于学习和使用。它采用了C++的部分语法,但去除了许多容易引起错误的特性,如指针。同时,Java引入了自动内存管理,即垃圾回收机制,减轻了程序员管理内存的负担。 - **...
4. **类与对象**:Java是面向对象的语言,一切皆为对象。类是对象的蓝图,包含属性(字段)和行为(方法)。对象则是类的实例,通过构造函数创建。 5. **封装、继承和多态**:封装是隐藏实现细节,提供公共接口;...