??xml version="1.0" encoding="utf-8" standalone="yes"?> 3)PriorityBlockingQueue:cM于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator军_的顺? 4)SynchronousQueue:Ҏ的BlockingQueue,对其的操作必L攑֒取交替完成的,是之前提q的BlockingQueue的又一实现。它l我们提供了在线E之间交换单一元素的极轻量U方? 其中LinkedBlockingQueue和ArrayBlockingQueue比较h,它们背后所用的数据l构不一?DLinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在U程数量很大时其性能的可预见性低于ArrayBlockingQueue. http://www.2cto.com/kf/201212/175028.html 术语 英文单词 描述 比较q交?/strong> Compare and Swap CAS操作需要输入两个数|一个旧|期望操作前的|和一个新|在操作期间先比较下旧值有没有发生变化Q如果没有发生变化,才交换成新|发生了变化则不交?/span>?/span> CPU水U?/span> CPU pipeline CPU水U的工作方式p工业生上的装配水U,在CPU中由5~6个不同功能的电\单元l成一条指令处理流水线Q然后将一条X86指o分成5~6步后再由q些电\单元分别执行Q这样就能实现在一个CPU旉周期完成一条指令,因此提高CPU的运速度?/span> 内存序冲突 Memory order violation 内存序冲突一般是由假׃n引vQ假׃n是指多个CPU同时修改同一个缓存行的不同部分而引起其中一个CPU的操作无效,当出现这个内存顺序冲H时QCPU必须清空水U?/span>?/span> ׃n变量 在多个线E之间能够被׃n的变量被UCؓ׃n变量。共享变量包括所有的实例变量Q静态变量和数组元素。他们都被存攑֜堆内存中QVolatile只作用于׃n变量?/span> 内存屏障 Memory Barriers 是一l处理器指oQ用于实现对内存操作的顺序限制?/span> ~冲?/strong> Cache line ~存中可以分配的最存储单位。处理器填写~存U时会加载整个缓存线Q需要用多个主内存d期?/span> 原子操作 Atomic operations 不可中断的一个或一pd操作?/span> ~存行填?/span> cache line fill 当处理器识别C内存中读取操作数是可~存的,处理器读取整个缓存行到适当的缓存(L1QL2QL3的或所有) ~存命中 cache hit 如果q行高速缓存行填充操作的内存位|仍然是下次处理器访问的地址Ӟ处理器从~存中读取操作数Q而不是从内存?/span> 写命?/span> write hit 当处理器操作数写回C个内存缓存的区域Ӟ它首先会查这个缓存的内存地址是否在缓存行中,如果存在一个有效的~存行,则处理器这个操作数写回到缓存,而不是写回到内存Q这个操作被UCؓ写命中?/span> 在ƈ发编E中很常用的实用工具cR此包包括了几个的、已标准化的可扩展框Ӟ以及一些提供有用功能的c,没有q些c,q些功能会很隑֮现或实现h冗长乏味。下面简要描qC要的lg。另请参?nbsp;locks ?nbsp;atomic 包?/p>
实现?/strong>c?nbsp; 此包中与某些cM起用的“Concurrent&rdquo前缀;是一U简写,表明与类似的“同步”cL所不同。例如,java.util.Hashtable ?tt>Collections.synchronizedMap(new HashMap()) 是同步的Q但 大多数ƈ?Collection 实现Q包括大多数 QueueQ与常规?java.util U定也不同,因ؓ它们的P代器提供?em>׃致的Q而不是快速失败的遍历。弱一致的q代器是U程安全的,但是在P代时没有必要ȝ collectionQ所以它不一定反映自q代器创Z来的所有更新?a id="MemoryVisibility" name="MemoryVisibility"> 条gQ也UCؓ条g队列 ?em>条g变量QؓU程提供了一个含义,以便在某个状态条件现在可能ؓ true 的另一个线E通知它之前,一直挂赯U程Q即让其“{待”Q。因问此׃n状态信息发生在不同的线E中Q所以它必须受保护,因此要将某种形式的锁与该条g相关联。等待提供一个条件的主要属性是Q?em>以原子方?/em> 释放相关的锁Qƈ挂v当前U程Q就?nbsp; 作ؓ一个示例,假定有一个绑定的~冲区,它支?nbsp; 注意Q?code>Condition 实例只是一些普通的对象Q它们自w可以用?nbsp; 除非另行说明Q否则ؓM参数传?nbsp; 在等?nbsp; 三种形式的条件等待(可中断、不可中断和时Q在一些^C的实C及它们的性能特征可能会有所不同。尤其是它可能很难提供这些特性和l护特定语义Q比如排序保证。更q一步地_中断U程实际挂v的能力在所有^Cq不是L可行的?/p>
因此Qƈ不要求某个实Cؓ所有三UŞ式的{待定义完全相同的保证或语义Q也不要求其支持中断U程的实际挂赗?/p>
要求实现清楚地记录每个等待方法提供的语义和保证,在某个实C支持中断U程的挂hQ它必须遵从此接口中定义的中断语义?/p>
术语 英文单词 描述 比较q交?/strong> Compare and Swap CAS操作需要输入两个数|一个旧|期望操作前的|和一个新|在操作期间先比较下旧值有没有发生变化Q如果没有发生变化,才交换成新|发生了变化则不交?/span>?/span> CPU水U?/span> CPU pipeline CPU水U的工作方式p工业生上的装配水U,在CPU中由5~6个不同功能的电\单元l成一条指令处理流水线Q然后将一条X86指o分成5~6步后再由q些电\单元分别执行Q这样就能实现在一个CPU旉周期完成一条指令,因此提高CPU的运速度?/span> 内存序冲突 Memory order violation 内存序冲突一般是由假׃n引vQ假׃n是指多个CPU同时修改同一个缓存行的不同部分而引起其中一个CPU的操作无效,当出现这个内存顺序冲H时QCPU必须清空水U?/span>?/span> ׃n变量 在多个线E之间能够被׃n的变量被UCؓ׃n变量。共享变量包括所有的实例变量Q静态变量和数组元素。他们都被存攑֜堆内存中QVolatile只作用于׃n变量?/span> 内存屏障 Memory Barriers 是一l处理器指oQ用于实现对内存操作的顺序限制?/span> ~冲?/strong> Cache line ~存中可以分配的最存储单位。处理器填写~存U时会加载整个缓存线Q需要用多个主内存d期?/span> 原子操作 Atomic operations 不可中断的一个或一pd操作?/span> ~存行填?/span> cache line fill 当处理器识别C内存中读取操作数是可~存的,处理器读取整个缓存行到适当的缓存(L1QL2QL3的或所有) ~存命中 cache hit 如果q行高速缓存行填充操作的内存位|仍然是下次处理器访问的地址Ӟ处理器从~存中读取操作数Q而不是从内存?/span> 写命?/span> write hit 当处理器操作数写回C个内存缓存的区域Ӟ它首先会查这个缓存的内存地址是否在缓存行中,如果存在一个有效的~存行,则处理器这个操作数写回到缓存,而不是写回到内存Q这个操作被UCؓ写命中?/span> 在ƈ发编E中很常用的实用工具cR此包包括了几个的、已标准化的可扩展框Ӟ以及一些提供有用功能的c,没有q些c,q些功能会很隑֮现或实现h冗长乏味。下面简要描qC要的lg。另请参?nbsp;locks ?nbsp;atomic 包?/p>
实现?/strong>c?nbsp; 此包中与某些cM起用的“Concurrent&rdquo前缀;是一U简写,表明与类似的“同步”cL所不同。例如,java.util.Hashtable ?tt>Collections.synchronizedMap(new HashMap()) 是同步的Q但 大多数ƈ?Collection 实现Q包括大多数 QueueQ与常规?java.util U定也不同,因ؓ它们的P代器提供?em>׃致的Q而不是快速失败的遍历。弱一致的q代器是U程安全的,但是在P代时没有必要ȝ collectionQ所以它不一定反映自q代器创Z来的所有更新?a id="MemoryVisibility" name="MemoryVisibility"> 条gQ也UCؓ条g队列 ?em>条g变量QؓU程提供了一个含义,以便在某个状态条件现在可能ؓ true 的另一个线E通知它之前,一直挂赯U程Q即让其“{待”Q。因问此׃n状态信息发生在不同的线E中Q所以它必须受保护,因此要将某种形式的锁与该条g相关联。等待提供一个条件的主要属性是Q?em>以原子方?/em> 释放相关的锁Qƈ挂v当前U程Q就?nbsp; 作ؓ一个示例,假定有一个绑定的~冲区,它支?nbsp; 注意Q?code>Condition 实例只是一些普通的对象Q它们自w可以用?nbsp; 除非另行说明Q否则ؓM参数传?nbsp; 在等?nbsp; 三种形式的条件等待(可中断、不可中断和时Q在一些^C的实C及它们的性能特征可能会有所不同。尤其是它可能很难提供这些特性和l护特定语义Q比如排序保证。更q一步地_中断U程实际挂v的能力在所有^Cq不是L可行的?/p>
因此Qƈ不要求某个实Cؓ所有三UŞ式的{待定义完全相同的保证或语义Q也不要求其支持中断U程的实际挂赗?/p>
要求实现清楚地记录每个等待方法提供的语义和保证,在某个实C支持中断U程的挂hQ它必须遵从此接口中定义的中断语义?/p>
如果使用 synchronized Q如果A不释放,B一直等下去Q不能被中断
如果 使用ReentrantLockQ如果A不释放,可以使B在等待了_长的旉以后Q中断等待,而干别的事情
ReentrantLock获取锁定与三U方式:
a) lock(), 如果获取了锁立即q回Q如果别的线E持有锁Q当前线E则一直处于休眠状态,直到获取?br /> b) tryLock(), 如果获取了锁立即q回trueQ如果别的线E正持有锁,立即q回falseQ?br /> c)tryLock(long timeout,TimeUnit unit)Q? 如果获取了锁定立卌回trueQ如果别的线E正持有锁,会等待参数给定的旉Q在{待的过E中Q如果获取了锁定Q就q回trueQ如果等待超Ӟq回falseQ?br /> d) lockInterruptibly:如果获取了锁定立卌回,如果没有获取锁定Q当前线E处于休眠状态,直到或者锁定,或者当前线E被别的U程中断
2、synchronized是在JVM层面上实现的Q不但可以通过一些监控工L控synchronized的锁定,而且在代码执行时出现异常QJVM会自动释N定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,必dunLock()攑ֈfinally{}?br />
3、在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLockQ但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;
]]>
]]>volatile 使用条g(必须同时满所有条?/span>):
高ƈ发术?/h2>
synchronized
volatile
concurrent
执行E序
接口?/span>Executor
是一个简单的标准化接口,用于定义cM于线E的自定义子pȝQ包括线E池、异?IO 和轻量d框架。根据所使用的具?Executor cȝ不同Q可能在新创建的U程中,现有的Q务执行线E中Q或者调?nbsp;execute() 的线E中执行dQƈ且可能顺序或q发执行?/span>ExecutorService
提供了多个完整的异步d执行框架。ExecutorService 理d的排队和安排Qƈ允许受控制的关闭?/span>ScheduledExecutorService
子接口及相关的接口添加了对gq的和定期Q务执行的支持。ExecutorService 提供了安排异步执行的ҎQ可执行?nbsp;Callable
表示的Q何函敎ͼl果cM?nbsp;Runnable
?/span>Future
q回函数的结果,允许定执行是否完成Qƈ提供取消执行的方法?/span>RunnableFuture
是拥?nbsp;run Ҏ?FutureQ?/span>run Ҏ执行时将讄其结果?/span>
ThreadPoolExecutor
?nbsp;ScheduledThreadPoolExecutor
提供可调的、灵zȝU程池?a title="java.util.concurrent 中的c? href="">Executors
cL供大多数 Executor 的常见类型和配置的工厂方法,以及使用它们的几U实用工h法。其他基?Executor 的实用工具包括具体类 FutureTask
Q它提供 Future 的常见可扩展实现Q以?nbsp;ExecutorCompletionService
Q它有助于协调对异步dl的处理?/p>
队列
java.util.concurrent ConcurrentLinkedQueue
cL供了高效的、可伸羃的、线E安全的非阻?FIFO 队列。java.util.concurrent 中的五个实现都支持扩展的 BlockingQueue
接口Q该接口定义?put ?take 的阻塞版本:LinkedBlockingQueue
?/span>ArrayBlockingQueue
?/span>SynchronousQueue
?/span>PriorityBlockingQueue
?nbsp;DelayQueue
。这些不同的c覆盖了生?使用者、消息传递、ƈ行Q务执行和相关q发设计的大多数常见使用的上下文?/span>BlockingDeque
接口扩展 BlockingQueueQ以支持 FIFO ?LIFOQ基于堆栈)操作?/span>LinkedBlockingDeque
cL供一个实现?/span>
计时
TimeUnit
cMؓ指定和控制基于超时的操作提供了多重粒度(包括U秒U)。该包中的大多数c除了包含不定的等待之外,q包含基于超时的操作。在使用时的所有情况中Q超时指定了在表明已时前该Ҏ应该{待的最时间。在时发生后,实现?#8220;力”超时。但是,在检超时与时之后再次实际执行U程之间可能要经q不定的时间。接受超时期参数的所有方法将于{于 0 的D为根本不会等待。要“永远”{待Q可以?nbsp;Long.MAX_VALUE 倹{?/span>
同步?/h2>四个cd协助实现常见的专用同步语句?/span>
Semaphore
是一个经典的q发工具?/span>CountDownLatch
是一个极其简单但又极其常用的实用工具Q用于在保持l定数目的信受事件或条g前阻塞执行?/span>CyclicBarrier
是一个可重置的多路同步点Q在某些q行~程风格中很有用?/span>Exchanger
允许两个U程?collection 点交换对象,它在多流水线设计中是有用的?/span>
q发 Collection
除队列外Q此包还提供了设计用于多U程上下文中?Collection 实现Q?/span>ConcurrentHashMap
?/span>ConcurrentSkipListMap
?/span>ConcurrentSkipListSet
?/span>CopyOnWriteArrayList
?nbsp;CopyOnWriteArraySet
。当期望许多U程讉K一个给?collection ӞConcurrentHashMap 通常优于同步?nbsp;HashMapQ?/span>ConcurrentSkipListMap 通常优于同步?nbsp;TreeMap。当期望的读数和遍历q远大于列表的更新数ӞCopyOnWriteArrayList 优于同步?nbsp;ArrayList?/span>
ConcurrentHashMap
则是“q发?#8221;。ƈ?collection 是线E安全的Q但是不受单个排他锁的管理。在 ConcurrentHashMap q一特定情况下,它可以安全地允许q行L数目的ƈ发读取,以及数目可调的ƈ发写入。需要通过单个锁不允许?collection 的所有访问时Q?#8220;同步”cL很有用的Q其代h是较差的可~性。在期望多个U程讉K公共 collection 的其他情况中Q通常“q发”版本要更好一些。当 collection 是未׃n的,或者仅保持其他锁时 collection 是可讉K的情况下Q非同步 collection 则要更好一些?/p>
内存一致性属?/a>
Java Language Specification W?17 ?/a>定义了内存操作(如共享变量的dQ的 happen-before 关系。只有写入操?strong> synchronized
?nbsp;volatile
构?nbsp;happen-before 关系Q?/span>Thread.start()
?/span>Thread.join()
Ҏ形成 happen-before 关系。尤其是Q?/span>
synchronized
d或方法进入)。ƈ且因?nbsp;happen-before 关系是可传递的Q所以解除锁定之前的U程的所有操?nbsp;happen-before 锁定该监视器的Q何线E后l的所有操作?/li>volatile
字段 happen-before 每个后箋d相同字段?code>volatile 字段的读取和写入与进入和退出监视器h怼的内存一致性效果,?em>?/em> 需要互斥锁?/li>start
happen-before 已启动的U程中的MU程?/li>join
成功q回的Q何其他线E?/li>java.util.concurrent
中所有类的方法及其子包扩展了q些Ҏ高别同步的保证。尤其是Q?/span>
Executor
提交 Runnable
之前的操?nbsp;happen-before 其执行开始。同样适用于向 ExecutorService
提交 Callables
?/li>Future
表示Q所采取的操?nbsp;happen-before 通过另一U程?nbsp;Future.get()
获取l果后箋的操作?/li>Lock.unlock
?code>Semaphore.release ?nbsp;CountDownLatch.countDown
Q之前的操作 happen-before 另一U程中相同同步储存对象成?#8220;获取”ҎQ如 Lock.lock
?code>Semaphore.acquire?code>Condition.await ?nbsp;CountDownLatch.await
Q的后箋操作?/li>Exchanger
成功交换对象的每个线E对Q每个线E中 exchange()
之前的操?nbsp;happen-before 另一U程中对?nbsp;exchange()
后箋的操作?/li>CyclicBarrier.await
之前的操?nbsp;happen-before 屏障操作所执行的操作,屏障操作所执行的操?nbsp;happen-before 从另一U程中对?code>await 成功q回的后l操作?/li>Condition
Condition
?nbsp;Object
监视器方法(wait
?a href="">notify
?nbsp;notifyAll
Q分解成截然不同的对象,以便通过这些对象与L Lock
实现l合使用Qؓ每个对象提供多个{待 setQwait-setQ。其中,Lock
替代?nbsp;synchronized
Ҏ和语句的使用Q?code>Condition 替代?Object 监视器方法的使用?/p>
Object.wait
做的那样?/p>
Condition
实例实质上被l定C个锁上。要为特?nbsp;Lock
实例获得 Condition
实例Q请使用?nbsp;newCondition()
Ҏ?/p>
put
?nbsp;take
Ҏ。如果试囑֜I的~冲Z执行 take
操作Q则在某一个项变得可用之前Q线E将一直阻塞;如果试图在满的缓冲区上执?nbsp;put
操作Q则在有I间变得可用之前Q线E将一直阻塞。我们喜Ƣ在单独的等?set 中保?nbsp;put
U程?nbsp;take
U程Q这样就可以在缓冲区中的ҎI间变得可用时利用最佌划,一ơ只通知一个线E。可以用两?nbsp;Condition
实例来做到这一炏V?/p> class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
Q?/span>ArrayBlockingQueue
cL供了q项功能Q因此没有理由去实现q个CZcR)
Condition
实现可以提供不同?nbsp;Object
监视器方法的行ؓ和语义,比如受保证的通知排序Q或者在执行通知时不需要保持一个锁。如果某个实现提供了q样Ҏ的语义,则该实现必须记录q些语义?/p>
synchronized
语句中的目标Qƈ且可以调用自q wait
?a href="">notification
监视器方法。获?nbsp;Condition
实例的监视器锁或者用其监视器方法,与获取和?nbsp;Condition
相关?nbsp;Lock
或用其 waiting
?nbsp;signalling
Ҏ没有什么特定的关系。ؓ了避免淆,除了在其自n的实C之外Q切勿以q种方式使用Condition
实例?/p>
null
值将D抛出 NullPointerException
?/p>
实现注意事项
Condition
Ӟ允许发生“虚假唤醒”Q这通常作ؓ对基q_语义的让步。对于大多数应用E序Q这带来的实际媄响很,因ؓ Condition
应该L在一个@环中被等待,q测试正被等待的状态声明。某个实现可以随意移除可能的虚假唤醒Q但应用E序E序员L假定q些虚假唤醒可能发生Q因此L在一个@环中{待?/p>
]]>
?
volatile 使用条g(必须同时满所有条?/span>):
高ƈ发术?/h2>
synchronized
volatile
concurrent
执行E序
接口?/span>Executor
是一个简单的标准化接口,用于定义cM于线E的自定义子pȝQ包括线E池、异?IO 和轻量d框架。根据所使用的具?Executor cȝ不同Q可能在新创建的U程中,现有的Q务执行线E中Q或者调?nbsp;execute() 的线E中执行dQƈ且可能顺序或q发执行?/span>ExecutorService
提供了多个完整的异步d执行框架。ExecutorService 理d的排队和安排Qƈ允许受控制的关闭?/span>ScheduledExecutorService
子接口及相关的接口添加了对gq的和定期Q务执行的支持。ExecutorService 提供了安排异步执行的ҎQ可执行?nbsp;Callable
表示的Q何函敎ͼl果cM?nbsp;Runnable
?/span>Future
q回函数的结果,允许定执行是否完成Qƈ提供取消执行的方法?/span>RunnableFuture
是拥?nbsp;run Ҏ?FutureQ?/span>run Ҏ执行时将讄其结果?/span>
ThreadPoolExecutor
?nbsp;ScheduledThreadPoolExecutor
提供可调的、灵zȝU程池?a title="java.util.concurrent 中的c? href="">Executors
cL供大多数 Executor 的常见类型和配置的工厂方法,以及使用它们的几U实用工h法。其他基?Executor 的实用工具包括具体类 FutureTask
Q它提供 Future 的常见可扩展实现Q以?nbsp;ExecutorCompletionService
Q它有助于协调对异步dl的处理?/p>
队列
java.util.concurrent ConcurrentLinkedQueue
cL供了高效的、可伸羃的、线E安全的非阻?FIFO 队列。java.util.concurrent 中的五个实现都支持扩展的 BlockingQueue
接口Q该接口定义?put ?take 的阻塞版本:LinkedBlockingQueue
?/span>ArrayBlockingQueue
?/span>SynchronousQueue
?/span>PriorityBlockingQueue
?nbsp;DelayQueue
。这些不同的c覆盖了生?使用者、消息传递、ƈ行Q务执行和相关q发设计的大多数常见使用的上下文?/span>BlockingDeque
接口扩展 BlockingQueueQ以支持 FIFO ?LIFOQ基于堆栈)操作?/span>LinkedBlockingDeque
cL供一个实现?/span>
计时
TimeUnit
cMؓ指定和控制基于超时的操作提供了多重粒度(包括U秒U)。该包中的大多数c除了包含不定的等待之外,q包含基于超时的操作。在使用时的所有情况中Q超时指定了在表明已时前该Ҏ应该{待的最时间。在时发生后,实现?#8220;力”超时。但是,在检超时与时之后再次实际执行U程之间可能要经q不定的时间。接受超时期参数的所有方法将于{于 0 的D为根本不会等待。要“永远”{待Q可以?nbsp;Long.MAX_VALUE 倹{?/span>
同步?/h2>四个cd协助实现常见的专用同步语句?/span>
Semaphore
是一个经典的q发工具?/span>CountDownLatch
是一个极其简单但又极其常用的实用工具Q用于在保持l定数目的信受事件或条g前阻塞执行?/span>CyclicBarrier
是一个可重置的多路同步点Q在某些q行~程风格中很有用?/span>Exchanger
允许两个U程?collection 点交换对象,它在多流水线设计中是有用的?/span>
q发 Collection
除队列外Q此包还提供了设计用于多U程上下文中?Collection 实现Q?/span>ConcurrentHashMap
?/span>ConcurrentSkipListMap
?/span>ConcurrentSkipListSet
?/span>CopyOnWriteArrayList
?nbsp;CopyOnWriteArraySet
。当期望许多U程讉K一个给?collection ӞConcurrentHashMap 通常优于同步?nbsp;HashMapQ?/span>ConcurrentSkipListMap 通常优于同步?nbsp;TreeMap。当期望的读数和遍历q远大于列表的更新数ӞCopyOnWriteArrayList 优于同步?nbsp;ArrayList?/span>
ConcurrentHashMap
则是“q发?#8221;。ƈ?collection 是线E安全的Q但是不受单个排他锁的管理。在 ConcurrentHashMap q一特定情况下,它可以安全地允许q行L数目的ƈ发读取,以及数目可调的ƈ发写入。需要通过单个锁不允许?collection 的所有访问时Q?#8220;同步”cL很有用的Q其代h是较差的可~性。在期望多个U程讉K公共 collection 的其他情况中Q通常“q发”版本要更好一些。当 collection 是未׃n的,或者仅保持其他锁时 collection 是可讉K的情况下Q非同步 collection 则要更好一些?/p>
内存一致性属?/a>
Java Language Specification W?17 ?/a>定义了内存操作(如共享变量的dQ的 happen-before 关系。只有写入操?strong> synchronized
?nbsp;volatile
构?nbsp;happen-before 关系Q?/span>Thread.start()
?/span>Thread.join()
Ҏ形成 happen-before 关系。尤其是Q?/span>
synchronized
d或方法进入)。ƈ且因?nbsp;happen-before 关系是可传递的Q所以解除锁定之前的U程的所有操?nbsp;happen-before 锁定该监视器的Q何线E后l的所有操作?/li>volatile
字段 happen-before 每个后箋d相同字段?code>volatile 字段的读取和写入与进入和退出监视器h怼的内存一致性效果,?em>?/em> 需要互斥锁?/li>start
happen-before 已启动的U程中的MU程?/li>join
成功q回的Q何其他线E?/li>java.util.concurrent
中所有类的方法及其子包扩展了q些Ҏ高别同步的保证。尤其是Q?/span>
Executor
提交 Runnable
之前的操?nbsp;happen-before 其执行开始。同样适用于向 ExecutorService
提交 Callables
?/li>Future
表示Q所采取的操?nbsp;happen-before 通过另一U程?nbsp;Future.get()
获取l果后箋的操作?/li>Lock.unlock
?code>Semaphore.release ?nbsp;CountDownLatch.countDown
Q之前的操作 happen-before 另一U程中相同同步储存对象成?#8220;获取”ҎQ如 Lock.lock
?code>Semaphore.acquire?code>Condition.await ?nbsp;CountDownLatch.await
Q的后箋操作?/li>Exchanger
成功交换对象的每个线E对Q每个线E中 exchange()
之前的操?nbsp;happen-before 另一U程中对?nbsp;exchange()
后箋的操作?/li>CyclicBarrier.await
之前的操?nbsp;happen-before 屏障操作所执行的操作,屏障操作所执行的操?nbsp;happen-before 从另一U程中对?code>await 成功q回的后l操作?/li>Condition
Condition
?nbsp;Object
监视器方法(wait
?a href="">notify
?nbsp;notifyAll
Q分解成截然不同的对象,以便通过这些对象与L Lock
实现l合使用Qؓ每个对象提供多个{待 setQwait-setQ。其中,Lock
替代?nbsp;synchronized
Ҏ和语句的使用Q?code>Condition 替代?Object 监视器方法的使用?/p>
Object.wait
做的那样?/p>
Condition
实例实质上被l定C个锁上。要为特?nbsp;Lock
实例获得 Condition
实例Q请使用?nbsp;newCondition()
Ҏ?/p>
put
?nbsp;take
Ҏ。如果试囑֜I的~冲Z执行 take
操作Q则在某一个项变得可用之前Q线E将一直阻塞;如果试图在满的缓冲区上执?nbsp;put
操作Q则在有I间变得可用之前Q线E将一直阻塞。我们喜Ƣ在单独的等?set 中保?nbsp;put
U程?nbsp;take
U程Q这样就可以在缓冲区中的ҎI间变得可用时利用最佌划,一ơ只通知一个线E。可以用两?nbsp;Condition
实例来做到这一炏V?/p> class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
Q?/span>ArrayBlockingQueue
cL供了q项功能Q因此没有理由去实现q个CZcR)
Condition
实现可以提供不同?nbsp;Object
监视器方法的行ؓ和语义,比如受保证的通知排序Q或者在执行通知时不需要保持一个锁。如果某个实现提供了q样Ҏ的语义,则该实现必须记录q些语义?/p>
synchronized
语句中的目标Qƈ且可以调用自q wait
?a href="">notification
监视器方法。获?nbsp;Condition
实例的监视器锁或者用其监视器方法,与获取和?nbsp;Condition
相关?nbsp;Lock
或用其 waiting
?nbsp;signalling
Ҏ没有什么特定的关系。ؓ了避免淆,除了在其自n的实C之外Q切勿以q种方式使用Condition
实例?/p>
null
值将D抛出 NullPointerException
?/p>
实现注意事项
Condition
Ӟ允许发生“虚假唤醒”Q这通常作ؓ对基q_语义的让步。对于大多数应用E序Q这带来的实际媄响很,因ؓ Condition
应该L在一个@环中被等待,q测试正被等待的状态声明。某个实现可以随意移除可能的虚假唤醒Q但应用E序E序员L假定q些虚假唤醒可能发生Q因此L在一个@环中{待?/p>
http://blog.csdn.net/fh13760184/article/details/8551546#
]]>
一Q高q发高负载类|站x点之数据?
没错,首先是数据库,q是大多数应用所面的首个SPOF。尤其是Web2.0的应用,数据库的响应是首先要解决的?br />一般来说MySQL是最常用的,可能最初是一个mysqlLQ当数据增加?00万以上,那么QMySQL的效能急剧下降。常用的优化措施是M-SQ主-从)方式q行同步复制Q将查询和操作和分别在不同的服务器上q行操作。我推荐的是M-M-Slaves方式Q?个主MysqlQ多个SlavesQ需要注意的是,虽然?个MasterQ但是同时只?个是ActiveQ我们可以在一定时候切换。之所以用2个MQ是保证M不会又成为系l的SPOF?br />Slaves可以q一步负载均衡,可以l合LVS,从而将select操作适当的^衡到不同的slaves上?br />以上架构可以抗衡C定量的负载,但是随着用户q一步增加,你的用户表数据超q?千万Q这旉个M变成了SPOF。你不能L扩充SlavesQ否则复制同步的开销直U上升,怎么办?我的Ҏ是表分区Q从业务层面上进行分区。最单的Q以用户数据Z。根据一定的切分方式Q比如idQ切分到不同的数据库集群厅R?
全局数据库用于meta数据的查询。缺Ҏ每次查询Q会增加一ơ,比如你要查一个用户nightsailer,你首先要到全局数据库群扑ֈnightsailer对应的cluster idQ然后再到指定的cluster扑ֈnightsailer的实际数据?br />每个cluster可以用m-m方式Q或者m-m-slaves方式。这是一个可以扩展的l构Q随着负蝲的增加,你可以简单的增加新的mysql clusterq去?/p>
需要注意的是:
1、禁用全部auto_increment的字D?br />2、id需要采用通用的算法集中分?br />3、要h比较好的Ҏ来监控mysqlL的负载和服务的运行状态。如果你?0C上的mysql数据库在跑就明白我的意思了?br />4、不要用持久性链接(不要用pconnectQ?相反Q用sqlrelayq种W三方的数据库链接池Q或者干脆自己做Q因为php4中mysql的链接池l常出问题?br />
二:高ƈ发高负蝲|站的系l架构之HTML静态化
其实大家都知道,效率最高、消耗最的是U?a target="_blank">静态化 http://www.ablanxue.com/shtml/201207/776.shtml的html面Q所以我们尽可能使我们的|站上的面采用静态页面来实现Q这个最单的Ҏ其实也是 最有效的方法。但是对于大量内容ƈ且频J更新的|站Q我们无法全部手动去挨个实现Q于是出C我们常见的信息发布系lCMSQ像我们常访问的各个门户站点 的新闻频道,甚至他们的其他频道,都是通过信息发布pȝ来管理和实现的,信息发布pȝ可以实现最单的信息录入自动生成静态页面,q能具备频道理、权?理、自动抓取等功能Q对于一个大型网站来_拥有一套高效、可理的CMS是必不可的?br />
除了门户和信息发布类型的|站Q对于交互性要求很高的Ccd|站来说Q尽可能的静态化也是提高性能的必要手D,社区内的帖子、文章进行实时的静态化Q有更新的时候再重新静态化也是大量使用的策略,像Mop的大杂烩是使用了这L{略Q网易社区等也是如此?br />
同时Qhtml静态化也是某些~存{略使用的手D,对于pȝ中频J用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实玎ͼ比如论坛 中论坛的公用讄信息Q这些信息目前的L论坛都可以进行后台管理ƈ且存储再数据库中Q这些信息其实大量被前台E序调用Q但是更新频率很,可以考虑这 部分内容q行后台更新的时候进行静态化Q这样避免了大量的数据库讉Kh高ƈ发?br />
|站HTML静态化解决Ҏ
当一个Servlet资源h到达WEB服务器之后我们会填充指定的JSP面来响应请?
HTTPh---Web服务?--Servlet--业务逻辑处理--讉K数据--填充JSP--响应h
HTML静态化之后:
HTTPh---Web服务?--Servlet--HTML--响应h
静态访求如?/p>
Servlet:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if(request.getParameter("chapterId") != null){
String chapterFileName = "bookChapterRead_"+request.getParameter("chapterId")+".html";
String chapterFilePath = getServletContext().getRealPath("/") + chapterFileName;
File chapterFile = new File(chapterFilePath);
if(chapterFile.exists()){response.sendRedirect(chapterFileName);return;}//如果有这个文件就告诉览器{?nbsp;
INovelChapterBiz novelChapterBiz = new NovelChapterBizImpl();
NovelChapter novelChapter = novelChapterBiz.searchNovelChapterById(Integer.parseInt(request.getParameter("chapterId")));//章节信息
int lastPageId = novelChapterBiz.searchLastCHapterId(novelChapter.getNovelId().getId(), novelChapter.getId());
int nextPageId = novelChapterBiz.searchNextChapterId(novelChapter.getNovelId().getId(), novelChapter.getId());
request.setAttribute("novelChapter", novelChapter);
request.setAttribute("lastPageId", lastPageId);
request.setAttribute("nextPageId", nextPageId);
new CreateStaticHTMLPage().createStaticHTMLPage(request, response, getServletContext(),
chapterFileName, chapterFilePath, "/bookRead.jsp");
}
}
生成HTML静态页面的c?
package com.jb.y2t034.thefifth.web.servlet;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/**
* 创徏HTML静态页?
* 功能Q创建HTML静态页?
* 旉Q?009q?011?
* 地点Qhome
* @author mavk
*
*/
public class CreateStaticHTMLPage {
/**
* 生成静态HTML面的方?
* @param request h对象
* @param response 响应对象
* @param servletContext Servlet上下?
* @param fileName 文g名称
* @param fileFullPath 文g完整路径
* @param jspPath 需要生成静态文件的JSP路径(相对卛_)
* @throws IOException
* @throws ServletException
*/
public void createStaticHTMLPage(HttpServletRequest request, HttpServletResponse response,ServletContext servletContext,String fileName,String fileFullPath,String jspPath) throws ServletException, IOException{
response.setContentType("text/html;charset=gb2312");//讄HTMLl果编?即HTML文g~码)
RequestDispatcher rd = servletContext.getRequestDispatcher(jspPath);//得到JSP资源
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();//用于从ServletOutputStream中接收资?nbsp;
final ServletOutputStream servletOuputStream = new ServletOutputStream(){//用于从HttpServletResponse中接收资?nbsp;
public void write(byte[] b, int off,int len){
byteArrayOutputStream.write(b, off, len);
}
public void write(int b){
byteArrayOutputStream.write(b);
}
};
final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream));//把{换字节流转换成字W流
HttpServletResponse httpServletResponse = new HttpServletResponseWrapper(response){//用于从response获取l果资?重写了两个方?
public ServletOutputStream getOutputStream(){
return servletOuputStream;
}
public PrintWriter getWriter(){
return printWriter;
}
};
rd.include(request, httpServletResponse);//发送结果流
printWriter.flush();//h~冲区,把缓冲区的数据输?nbsp;
FileOutputStream fileOutputStream = new FileOutputStream(fileFullPath);
byteArrayOutputStream.writeTo(fileOutputStream);//把byteArrayOuputStream中的资源全部写入到fileOuputStream?nbsp;
fileOutputStream.close();//关闭输出,q攄兌?nbsp;
response.sendRedirect(fileName);//发送指定文件流到客L
}
}
三:高ƈ发高负蝲cȝ站关注点之缓存、负载均衡、存?
~存是另一个大问题Q我一般用memcached来做~存集群Q一般来说部|?0台左叛_差不多(10g内存池)。需要注意一点,千万不能用?br />swapQ最好关闭linux的swap?/p>
负蝲均衡/加?br />
可能上面说缓存的时候,有hW一想的是页面静态化Q所谓的静态htmlQ我认ؓq是常识Q不属于要点了。页面的静态化随之带来的是静态服务的
负蝲均衡和加速。我认ؓLighttped+Squid是最好的方式了?br />LVS <------->lighttped====>squid(s) ====lighttpd
上面是我l常用的。注意,我没有用apacheQ除非特定的需求,否则我不部vapacheQ因为我一般用php-fastcgi配合lighttpd,
性能比apache+mod_php要强很多?/p>
squid的用可以解x件的同步{等问题Q但是需要注意,你要很好的监控缓存的命中率,可能的提高?0%以上?br />squid和lighttped也有很多的话题要讨论Q这里不赘述?/p>
存储
存储也是一个大问题Q一U是文件的存储Q比如图片这cR另一U是大文件的存储Q比如搜索引擎的索引Q一般单文g都超q?g以上?br />文件的存储最单的Ҏ是结合lighttpd来进行分布。或者干脆用Redhat的GFSQ优Ҏ应用透明Q缺Ҏ费用较高。我是指
你购买盘늚问题。我的项目中Q存储量?-10TbQ我采用了分布式存储。这里要解决文g的复制和冗余?br />q样每个文g有不同的冗余Q这斚w可以参考google的gfs的论文?br />大文件的存储Q可以参考nutch的方案,现在已经独立为hadoop子项目?你可以google it)
其他Q?br />此外Qpassport{也是考虑的,不过都属于比较简单的了?br />四:高ƈ发高负蝲|站的系l架构之囄服务器分?
大家知道Q对于Web 服务器来_不管是Apache、IISq是其他容器Q图片是最消耗资源的Q于是我们有必要图片与面q行分离Q这是基本上大型|站都会采用的策略,?们都有独立的囄服务器,甚至很多台图片服务器。这L架构可以降低提供面讉Kh的服务器pȝ压力Qƈ且可以保证系l不会因为图片问题而崩溃,在应?服务器和囄服务器上Q可以进行不同的配置优化Q比如apache在配|ContentType的时候可以尽量少支持Q尽可能的LoadModuleQ?保证更高的系l消耗和执行效率?
利用Apache实现囄服务器的分离
~由Q?
h阶段的应用,都可能部|在一台服务器上(费用上的原因Q?
W一个优先分ȝQ肯定是数据库和应用服务器?
W二个分ȝQ会是什么呢Q各有各的考虑Q我所在的目l重点考虑的节U带宽,服务器性能再好Q带宽再高,q发来了Q也Ҏ撑不住。因此,我这文章的重点在这里。这里重Ҏ介绍实践Q不一定符合所有情况,供看者参考吧Q?
环境介绍Q?
WEB应用服务器:4CPU双核2G, 内存4G
部vQWin2003/Apache Http Server 2.1/Tomcat6
数据库服务器Q?CPU双核2G, 内存4G
部vQWin2003/MSSQL2000
步骤Q?
步骤一Q增?台配|ؓQ?CPU双核2GQ内?G普通服务器Q做资源服务?
部vQTomcat6Q跑了一个图片上传的单应用,Q记得指定web.xml?lt;distributable/>Q,q指定域名ؓres1.***.com,res2.***.comQ采用ajp协议
步骤二:修改Apache httpd.conf配置
原来应用的文件上传功能网址为:
1?fileupload.html
2?otherupload.html
在httpd.conf中增加如下配|?
<VirtualHost *:80>
ServerAdmin webmaster@***.com
ProxyPass /fileupload.html balancer://rescluster/fileupload lbmethod=byrequests stickysession=JSESSIONID nofailover=Off timeout=5 maxattempts=3
ProxyPass /otherupload.html balancer://rescluster/otherupload.html lbmethod=byrequests stickysession=JSESSIONID nofailover=Off timeout=5 maxattempts=3
#<!--负蝲均衡-->
<Proxy balancer://rescluster/>
BalancerMember ajp://res1.***.com:8009 smax=5 max=500 ttl=120 retry=300 loadfactor=100 route=tomcat1
BalancerMember ajp://res2.***.com:8009 smax=5 max=500 ttl=120 retry=300 loadfactor=100 route=tomcat2
</Proxy>
</VirtualHost>
步骤三,修改业务逻辑Q?
所有上传文件在数据库中均采用全url的方式保存,例如产品囄路径存成Qhttp://res1.***.com/upload/20090101/product120302005.jpg
现在Q你可以高枕无忧了,带宽不够Ӟ增加个几十台囄服务器,只需要稍微修改一下apache的配|文Ӟ卛_?
五:高ƈ发高负蝲|站的系l架构之数据库集和库表散列
大型|站都有复杂的应用,q些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓉很快p昄出来Q这时一台数据库很快无法满_用,于是我们需要用数据库集群或者库表散列?br />
在数据库集群斚wQ很多数据库都有自己的解x案,Oracle、Sybase{都有很好的ҎQ常用的MySQL提供的Master/Slave也是cM的方案,您用了什么样的DBQ就参考相应的解决Ҏ来实施即可?br />
上面提到的数据库集群׃在架构、成本、扩张性方面都会受到所采用DBcd的限Ӟ于是我们需要从应用E序的角度来考虑改善pȝ架构Q库表散列是常用q?且最有效的解x案。我们在应用E序中安装业务和应用或者功能模块将数据库进行分,不同的模块对应不同的数据库或者表Q再按照一定的{略Ҏ个页面或?功能q行更小的数据库散列Q比如用戯Q按照用户IDq行表散列,q样p够低成本的提升系l的性能q且有很好的扩展性。sohu的论坛就是采用了q样?架构Q将论坛的用戗设|、帖子等信息q行数据库分,然后对帖子、用h照板块和IDq行散列数据库和表,最l可以在配置文g中进行简单的配置便能让系 l随时增加一C成本的数据库q来补充pȝ性能?
集群软g的分c:
一般来Ԍ集群软gҎ侧重的方向和试图解决的问题,分ؓ三大c:高性能集群QHigh performance clusterQHPCQ、负载均衡集(Load balance clusterQ?LBCQ,高可用性集(High availability clusterQHACQ?br />高性能集群QHigh performance clusterQHPCQ,它是利用一个集中的多台机器共同完成同一件Q务,使得完成d的速度和可靠性都q远高于单机q行的效果。I补了单机性能上的不。该集群在天气预报、环境监控等数据量大Q计复杂的环境中应用比较多Q?br />负蝲均衡集群QLoad balance clusterQ?LBCQ,它是利用一个集中的多台单机,完成许多q行的小的工作。一般情况下Q如果一个应用用的人多了,那么用户h的响应时间就会增大,机器的性能也会受到影响Q如果用负载均衡集,那么集群中Q意一台机器都能响应用LhQ这样集就会在用户发出服务h之后Q选择当时负蝲最,能够提供最好的服务的这台机器来接受hq相应,q样可用用集群来增加系l的可用性和E_性。这c集在|站中用较多;
高可用性集(High availability clusterQHACQ,它是利用集群中系l?的冗余,当系l中某台机器发生损坏的时候,其他后备的机器可以迅速的接替它来启动服务Q等待故障机的维修和q回。最大限度的保证集群中服务的可用性。这cȝl一般在银行Q电信服务这cdpȝ可靠性有高的要求的领域有着q泛的应用?br />2 数据库集的现状
数据库集是计机集群技术引入到数据库中来实现的Q尽各厂商宣称自己的架构如何的完美Q但是始l不能改变Oracle当先Q大家追逐的事实Q在集群的解x案上Oracle RACq是领先于包括微软在内的其它数据库厂商,它能满客户高可用性、高性能、数据库负蝲均衡和方便扩展的需求?br />Oracle’s Real Application Cluster (RAC)
Microsoft SQL Cluster Server (MSCS)
IBM’s DB2 UDB High Availability Cluster(UDB)
Sybase ASE High Availability Cluster (ASE)
MySQL High Availability Cluster (MySQL CS)
ZIO的第三方HA(高可用?集群
当前主要的数据库集群技术有以上六大c,有数据库厂商自己开发的Q也有第三方的集公司开发的Q还有数据库厂商与第三方集群公司合作开发的Q各c集实现的功能及架构也不尽相同?br />RACQReal Application ClusterQ真正应用集)是Oracle9i数据库中采用的一Ҏ技术,也是Oracle数据库支持网D环境的核心技术。它的出现解决了传统数据库应用中面的一个重要问题:高性能、高可~性与低hg间的矛盾。在很长一D|间里Q甲骨文都以其实时应用集技?Real Application ClusterQRAC)l治着集群数据库市?/p>
六:高ƈ发高负蝲|站的系l架构之~存
~存一词搞技术的都接触过Q很多地方用到缓存。网站架构和|站开发中的缓存也是非帔R要。这里先讲述最基本的两U缓存。高U和分布式的~存在后面讲q?
架构斚w的缓存,对Apache比较熟悉的h都能知道Apache提供了自q~存模块Q也可以使用外加的Squid模块q行~存Q这两种方式均可以有效的提高Apache的访问响应能力?br /> |站E序开发方面的~存QLinux上提供的Memory Cache是常用的~存接口Q可以在web开发中使用Q比如用Java开发的时候就可以调用MemoryCache对一些数据进行缓存和通讯׃nQ一些大 型社Z用了q样的架构。另外,在用web语言开发的时候,各种语言基本都有自己的缓存模块和ҎQPHP有Pear的Cache模块QJava更?了,.net不是很熟悉,怿也肯定有?
Java开源缓存框?
JBossCache/TreeCache JBossCache是一个复制的事务处理~存Q它允许你缓存企业应用数据来更好的改善性能。缓存数据被自动复制Q让你轻松进行Jboss服务器之间的集群工作。JBossCache能够通过Jboss应用服务或其他J2EE容器来运行一个Mbean服务Q当Ӟ它也能独立运行?JBossCache包括两个模块QTreeCache和TreeCacheAOP?TreeCache --是一个树形结构复制的事务处理~存?TreeCacheAOP --是一?#8220;面向对象”~存Q它使用AOP来动态管理POJO
OSCache OSCache标记库由OpenSymphony设计Q它是一U开创性的JSP定制标记应用Q提供了在现有JSP面之内实现快速内存缓冲的功能。OSCache是个一个广泛采用的高性能的J2EE~存框架QOSCache能用于Q何Java应用E序的普通的~存解决Ҏ。OSCache有以下特点:~存M对象Q你可以不受限制的缓存部分jsp面或HTTPhQQ何java对象都可以缓存?拥有全面的API--OSCache APIl你全面的程序来控制所有的OSCacheҎ?怹~存--~存能随意的写入盘Q因此允许昂늚创徏Qexpensive-to-createQ数据来保持~存Q甚臌让应用重启?支持集群--集群~存数据能被单个的进行参数配|,不需要修改代码?~存记录的过?-你可以有最大限度的控制~存对象的过期,包括可插入式的刷新策略(如果默认性能不需要时Q?br />JCACHE JCACHE是一U即公布的标准规范QJSR 107Q,说明了一U对Java对象临时在内存中q行~存的方法,包括对象的创建、共享访问、假脱机QspoolingQ、失效、各JVM的一致性等。它可被用于~存JSP内最l常d的数据,如品目录和h列表。利用JCACHEQ多数查询的反应旉会因为有~存的数据而加快(内部试表明反应旉大约?5倍)?br />Ehcache EhcacheHibernateQ在Hibernate中用它作ؓ数据~存的解x案?br />Java Caching System JCS是Jakarta的项目Turbine的子目。它是一个复合式的缓冲工兗可以将对象~冲到内存、硬盘。具有缓冲对象时间过期设定。还可以通过JCS构徏h~冲的分布式构架Q以实现高性能的应用?对于一些需要频J访问而每讉K一ơ都非常消耗资源的对象Q可以时存攑֜~冲ZQ这样可以提高服务的性能。而JCS正是一个很好的~冲工具。缓冲工具对于读操作q远多于写操作的应用性能提高非常显著?br />SwarmCache SwarmCache是一个简单而功能强大的分布式缓存机制。它使用IPl播来有效地在缓存的实例之间q行通信。它是快速提高集式Web应用E序的性能的理想选择?br />ShiftOne ShiftOne Object Cacheq个Java库提供了基本的对象缓存能力。实现的{略有先q先出(FIFOQ,最q用(LRUQ,最不常使用QLFUQ。所有的{略可以最大化元素的大,最大化其生存时间?br />WhirlyCache Whirlycache是一个快速的、可配置的、存在于内存中的对象的缓存。它能够通过~存对象来加快网站或应用E序的速度Q否则就必须通过查询数据库或其他代h较高的处理程序来建立?br />Jofti Jofti可对在缓存层?支持EHCacheQJBossCache和OSCache)的对象或在支持Map接口的存储结构中的对象进行烦引与搜烦。这个框架还为对象在索引中的增删Ҏ供透明的功能同样也为搜索提供易于用的查询功能?br />cache4j cache4j是一个有单API与实现快速的Java对象~存。它的特性包括:在内存中q行~存Q设计用于多U程环境Q两U实玎ͼ同步与阻塞,多种~存清除{略QLFU, LRU, FIFOQ可使用强引?strong reference)与Y引用(soft reference)存储对象?br /> Open Terracotta 一个JVMU的开源群集框Ӟ提供QHTTP Session复制Q分布式~存QPOJO集Q跨群集的JVM来实现分布式应用E序协调(采用代码注入的方式,所以你不需要修改Q??br /> sccache SHOP.COM使用的对象缓存系l。sccache是一个in-process cache和二U、共享缓存。它缓存对象存储到盘上。支持关联KeyQQ意大的Key和Q意大的数据。能够自动进行垃圾收集?br /> Shoal Shoal是一个基于Java可扩展的动态集框Ӟ能够为构建容错、可靠和可用的Java应用E序提供了基架构支持。这个框架还可以集成C希望l定到特定通信协议Q但需要集和分布式系l支持的MJava产品中。Shoal是GlassFish和JonAS应用服务器的集群引擎?br />Simple-Spring-Memcached Simple-Spring-MemcachedQ它装了对MemCached的调用,使MemCached的客L开发变得超乎寻常的单?br />