Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
JAVAḬ̈߳²È«¶ÓÁÐ
 
×÷Õߣºwhuan À´Ô´£ºCSDN ·¢²¼ÓÚ 2015-9-7
  2576  次浏览      27
 

ÔÚJava¶àÏß³ÌÓ¦ÓÃÖУ¬¶ÓÁеÄʹÓÃÂʺܸߣ¬¶àÊýÉú²úÏû·ÑÄ£Ð͵ÄÊ×Ñ¡Êý¾Ý½á¹¹¾ÍÊǶÓÁС£JavaÌṩµÄḬ̈߳²È«µÄQueue¿ÉÒÔ·ÖΪ×èÈû¶ÓÁкͷÇ×èÈû¶ÓÁС£

ÆäÖÐ×èÈû¶ÓÁеĵäÐÍÀý×ÓÊÇBlockingQueue£¬·Ç×èÈû¶ÓÁеĵäÐÍÀý×ÓÊÇConcurrentLinkedQueue£¬ÔÚʵ¼ÊÓ¦ÓÃÖÐÒª¸ù¾Ýʵ¼ÊÐèҪѡÓÃ×èÈû¶ÓÁлòÕß·Ç×èÈû¶ÓÁС£

Ê×ÏÈÁ˽âÏÂʲô½ÐḬ̈߳²È«£¿

Õâ¸öÊ×ÏÈÒªÃ÷È·¡£Ḭ̈߳²È«µÄÀà £¬Ö¸µÄÊÇÀàÄÚ¹²ÏíµÄÈ«¾Ö±äÁ¿µÄ·ÃÎʱØÐë±£Ö¤ÊDz»ÊܶàÏß³ÌÐÎʽӰÏìµÄ¡£Èç¹ûÓÉÓÚ¶àÏ̵߳ķÃÎÊ£¨±ÈÈçÐ޸ġ¢±éÀú¡¢²é¿´£©¶øÊ¹ÕâЩ±äÁ¿½á¹¹±»ÆÆ»µ»òÕßÕë¶ÔÕâЩ±äÁ¿²Ù×÷µÄÔ­×ÓÐÔ±»ÆÆ»µ£¬ÔòÕâ¸öÀà¾Í²»ÊÇḬ̈߳²È«µÄ¡£

Õâ´Î¾ÍÖ÷Òª¿´Á½ÖÖQueue:

BlockingQueue ×èÈûËã·¨

ConcurrentLinkedQueue£¬·Ç×èÈûËã·¨

Ê×ÏÈÀ´¿´¿´BlockingQueue£º

QueueÊÇʲô¾Í²»ÐèÒª¶à˵Á˰ɣ¬Ò»¾ä»°£º¶ÓÁÐÊÇÏȽøÏȳö¡£Ïà¶ÔµÄ£¬Õ»ÊǺó½øÏȳö¡£Èç¹û²»ÊìϤµÄ»°¿ÉÒÔÏÈÕÒ±¾»ù´¡µÄÊý¾Ý½á¹¹µÄÊé¿´¿´¡£

BlockingQueue£¬¹ËÃû˼Ò壬¡°×èÈû¶ÓÁС±£º¿ÉÒÔÌṩ×èÈû¹¦ÄܵĶÓÁС£

Ê×ÏÈ£¬¿´¿´BlockingQueueÌṩµÄ³£Ó÷½·¨£º

´ÓÉϱí¿ÉÒÔºÜÃ÷ÏÔ¿´³öÿ¸ö·½·¨µÄ×÷Óã¬ÕâÀïÐèҪעÒâµÄÊÇ£º

add(e) remove() element() ·½·¨²»»á×èÈûÏ̡߳£µ±²»Âú×ãÔ¼ÊøÌõ¼þʱ£¬»áÅ׳öIllegalStateException Òì³£¡£ÀýÈ磺µ±¶ÓÁб»ÔªËØÌîÂúºó£¬ÔÙµ÷ÓÃadd(e)£¬Ôò»áÅ׳öÒì³£¡£

offer(e) poll() peek() ·½·¨¼´²»»á×èÈûỊ̈߳¬Ò²²»»áÅ׳öÒì³£¡£ÀýÈ磺µ±¶ÓÁб»ÔªËØÌîÂúºó£¬ÔÙµ÷ÓÃoffer(e)£¬Ôò²»»á²åÈëÔªËØ£¬º¯Êý·µ»Øfalse¡£

ÒªÏëҪʵÏÖ×èÈû¹¦ÄÜ£¬ÐèÒªµ÷ÓÃput(e) take() ·½·¨¡£µ±²»Âú×ãÔ¼ÊøÌõ¼þʱ£¬»á×èÈûÏ̡߳£

ºÃ£¬ÉϵãÔ´Âë¾Í¸üÃ÷°×ÁË¡£ÒÔArrayBlockingQueueÀàΪÀý£º

¶ÔÓÚµÚÒ»Àà·½·¨£¬ºÜÃ÷ÏÔÈç¹û²Ù×÷²»³É¹¦¾ÍÅ×Òì³£¡£¶øÇÒ¿ÉÒÔ¿´µ½Æäʵµ÷ÓõÄÊǵڶþÀàµÄ·½·¨£¬ÎªÊ²Ã´£¿ÒòΪµÚ¶þÀà·½·¨·µ»Øboolean¡£

public boolean add(E e) {  
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");//¶ÓÁÐÒÑÂú£¬Å×Òì³£
}

public E remove() {
E x = poll();
if (x != null)
return x;
else
throw new NoSuchElementException();//¶ÓÁÐΪ¿Õ£¬Å×Òì³£
}

¶ÔÓÚµÚ¶þÀà·½·¨£¬ºÜ±ê×¼µÄReentrantLockʹÓ÷½Ê½£¬ÁíÍâ¶ÔÓÚinsertºÍextractµÄʵÏÖûɶºÃ˵µÄ¡£

×¢£ºÏȲ»¿´×èÈûÓë·ñ£¬ÕâReentrantLockµÄʹÓ÷½Ê½¾ÍÄÜ˵Ã÷Õâ¸öÀàÊÇḬ̈߳²È«Àà¡£

public boolean offer(E e) {  
if (e == null)throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)//¶ÓÁÐÒÑÂú£¬·µ»Øfalse
return false;
else {
insert(e);//insert·½·¨Öз¢³öÁËnotEmpty.signal();
return true;
}
} finally {
lock.unlock();
}
}

public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == 0)//¶ÓÁÐΪ¿Õ£¬·µ»Øfalse
return null;
E x = extract();//extract·½·¨Öз¢³öÁËnotFull.signal();
return x;
} finally {
lock.unlock();
}
}

¶ÔÓÚµÚÈýÀà·½·¨£¬ÕâÀïÃæÉæ¼°µ½ConditionÀ࣬¼òÒªÌáһϣ¬ await·½·¨Ö¸£ºÔì³Éµ±Ç°Ïß³ÌÔÚ½Óµ½ÐźŻò±»ÖжÏ֮ǰһֱ´¦Óڵȴý״̬¡£ signal·½·¨Ö¸£º»½ÐÑÒ»¸öµÈ´ýÏ̡߳£

public void put(E e)throws InterruptedException {  
if (e == null)throw new NullPointerException();
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (count == items.length)//Èç¹û¶ÓÁÐÒÑÂú£¬µÈ´ýnotFullÕâ¸öÌõ¼þ£¬Õâʱµ±Ç°Ï̱߳»×èÈû
notFull.await();
} catch (InterruptedException ie) {
notFull.signal(); //»½ÐÑÊÜnotFull×èÈûµÄµ±Ç°Ïß³Ì
throw ie;
}
insert(e);
} finally {
lock.unlock();
}
}

public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (count == 0)//Èç¹û¶ÓÁÐΪ¿Õ£¬µÈ´ýnotEmptyÕâ¸öÌõ¼þ£¬Õâʱµ±Ç°Ï̱߳»×èÈû
notEmpty.await();
} catch (InterruptedException ie) {
notEmpty.signal();//»½ÐÑÊÜnotEmpty×èÈûµÄµ±Ç°Ïß³Ì
throw ie;
}
E x = extract();
return x;
} finally {
lock.unlock();
}
}

µÚËÄÀà·½·¨¾ÍÊÇÖ¸ÔÚÓбØÒªÊ±µÈ´ýÖ¸¶¨Ê±¼ä£¬¾Í²»Ïêϸ˵ÁË¡£

ÔÙÀ´¿´¿´BlockingQueue½Ó¿ÚµÄ¾ßÌåʵÏÖÀà°É£º

ArrayBlockingQueue£¬Æä¹¹Ô캯Êý±ØÐë´øÒ»¸öint²ÎÊýÀ´Ö¸Ã÷Æä´óС

LinkedBlockingQueue£¬ÈôÆä¹¹Ô캯Êý´øÒ»¸ö¹æ¶¨´óСµÄ²ÎÊý£¬Éú³ÉµÄBlockingQueueÓдóСÏÞÖÆ£¬Èô²»´ø´óС²ÎÊý£¬ËùÉú³ÉµÄBlockingQueueµÄ´óСÓÉInteger.MAX_VALUEÀ´¾ö¶¨

PriorityBlockingQueue£¬ÆäËùº¬¶ÔÏóµÄÅÅÐò²»ÊÇFIFO,¶øÊÇÒÀ¾Ý¶ÔÏóµÄ×ÔÈ»ÅÅÐò˳Ðò»òÕßÊǹ¹Ô캯ÊýµÄComparator¾ö¶¨µÄ˳Ðò

ÉÏÃæÊÇÓÃArrayBlockingQueue¾ÙµÃÀý×Ó£¬ÏÂÃæ¿´¿´LinkedBlockingQueue£º

Ê×ÏÈ£¬¼ÈÈ»ÊÇÁ´±í£¬¾ÍÓ¦¸ÃÓÐNode½Úµã£¬ËüÊÇÒ»¸öÄÚ²¿¾²Ì¬Àࣺ

static class Node<E> {
/** The item, volatile to ensure barrier separating write and read */
volatile E item;
Node<E> next;
Node(E x) { item = x; }
}

È»ºó£¬¶ÔÓÚÁ´±íÀ´Ëµ£¬¿Ï¶¨ÐèÒªÁ½¸ö±äÁ¿À´±êʾͷºÍβ£º

/** Í·Ö¸Õë */
private transient Node<E> head;//head.nextÊǶÓÁеÄÍ·ÔªËØ
/** βָÕë */
private transient Node<E> last;//last.nextÊÇnull

ÄÇô£¬¶ÔÓÚÈë¶ÓºÍ³ö¶Ó¾ÍºÜ×ÔÈ»ÄÜÀí½âÁË£º

private void enqueue(E x) {  
last = last.next = new Node<E>(x);//Èë¶ÓÊÇΪlastÔÙÕÒ¸öϼÒ
}

private E dequeue() {
Node<E> first = head.next; //³ö¶ÓÊǰÑhead.nextÈ¡³öÀ´£¬È»ºó½«headÏòºóÒÆÒ»Î»
head = first;
E x = first.item;
first.item = null;
return x;
}

ÁíÍ⣬LinkedBlockingQueueÏà¶ÔÓÚArrayBlockingQueue»¹Óв»Í¬ÊÇ£¬ÓÐÁ½¸öReentrantLock£¬ÇÒ¶ÓÁÐÏÖÓÐÔªËØµÄ´óСÓÉÒ»¸öAtomicInteger¶ÔÏó±êʾ¡£

×¢£ºAtomicIntegerÀàÊÇÒÔÔ­×ӵķ½Ê½²Ù×÷ÕûÐͱäÁ¿¡£

private final AtomicInteger count =new AtomicInteger(0);
/** ÓÃÓÚ¶ÁÈ¡µÄ¶ÀÕ¼Ëø*/
private final ReentrantLock takeLock =new ReentrantLock();
/** ¶ÓÁÐÊÇ·ñΪ¿ÕµÄÌõ¼þ */
private final Condition notEmpty = takeLock.newCondition();
/** ÓÃÓÚдÈëµÄ¶ÀÕ¼Ëø */
private final ReentrantLock putLock =new ReentrantLock();
/** ¶ÓÁÐÊÇ·ñÒÑÂúµÄÌõ¼þ */
private final Condition notFull = putLock.newCondition();
ÓÐÁ½¸öConditionºÜºÃÀí½â£¬ÔÚArrayBlockingQueueÒ²ÊÇÕâÑù×öµÄ¡£ µ«ÊÇΪʲôÐèÒªÁ½¸öReentrantLockÄØ£¿ÏÂÃæ»áÂýÂýµÀÀ´¡£
ÈÃÎÒÃÇÀ´¿´¿´offerºÍpoll·½·¨µÄ´úÂ룺

<span style="font-size:14px;">public boolean offer(E e) {  
if (e == null)throw new NullPointerException();
final AtomicInteger count = this.count;
if (count.get() == capacity)
return false;
int c = -1;
final ReentrantLock putLock =this.putLock;//Èë¶Óµ±È»ÓÃputLock
putLock.lock();
try {
if (count.get() < capacity) {
enqueue(e); //Èë¶Ó
c = count.getAndIncrement(); //¶Ó³¤¶È+1
if (c + 1 < capacity)
notFull.signal(); //¶ÓÁÐûÂú£¬µ±È»¿ÉÒÔ½âËøÁË
}
} finally {
putLock.unlock();
}
if (c == 0)
signalNotEmpty();//Õâ¸ö·½·¨Àï·¢³öÁËnotEmpty.signal();
return c >= 0;
}

public E poll() {
final AtomicInteger count = this.count;
if (count.get() == 0)
return null;
E x = null;
int c = -1;
final ReentrantLock takeLock =this.takeLock;³ö¶Óµ±È»ÓÃtakeLock
takeLock.lock();
try {
if (count.get() > 0) {
x = dequeue();//³ö¶Ó
c = count.getAndDecrement();//¶Ó³¤¶È-1
if (c > 1)
notEmpty.signal();//¶ÓÁÐû¿Õ£¬½âËø
}
} finally {
takeLock.unlock();
}
if (c == capacity)
signalNotFull();//Õâ¸ö·½·¨Àï·¢³öÁËnotFull.signal();
return x;
}</span>

¿´Ô´´úÂë·¢ÏÖºÍÉÏÃæArrayBlockingQueueµÄºÜÀàËÆ£¬¹Ø¼üµÄÎÊÌâÔÚÓÚ£ºÎªÊ²Ã´ÒªÓÃÁ½¸öReentrantLockputLockºÍtakeLock£¿

ÎÒÃÇ×ÐϸÏëһϣ¬Èë¶Ó²Ù×÷Æäʵ²Ù×÷µÄÖ»ÓжÓβÒýÓÃlast£¬²¢ÇÒûÓÐÇ£Éæµ½head¡£¶ø³ö¶Ó²Ù×÷ÆäʵֻÕë¶Ôhead£¬ºÍlastûÓйØÏµ¡£ÄÇô¾ÍÊÇ˵Èë¶ÓºÍ³ö¶ÓµÄ²Ù×÷ÍêÈ«²»ÐèÒª¹«ÓÃÒ»°ÑËø£¬ËùÒÔ¾ÍÉè¼ÆÁËÁ½¸öËø£¬ÕâÑù¾ÍʵÏÖÁ˶à¸ö²»Í¬ÈÎÎñµÄÏß³ÌÈë¶ÓµÄͬʱ¿ÉÒÔ½øÐгö¶ÓµÄ²Ù×÷£¬ÁíÒ»·½ÃæÓÉÓÚÁ½¸ö²Ù×÷Ëù¹²Í¬Ê¹ÓõÄcountÊÇAtomicIntegerÀàÐ͵ģ¬ËùÒÔÍêÈ«²»Óÿ¼ÂǼÆÊýÆ÷µÝÔöµÝ¼õµÄÎÊÌâ¡£

ÁíÍ⣬»¹ÓÐÒ»µãÐèҪ˵Ã÷һϣºawait()ºÍsingal()ÕâÁ½¸ö·½·¨Ö´ÐÐʱ¶¼»á¼ì²éµ±Ç°Ïß³ÌÊÇ·ñÊǶÀÕ¼ËøµÄµ±Ç°Ị̈߳¬Èç¹û²»ÊÇÔòÅ׳öjava.lang.IllegalMonitorStateExceptionÒì³£¡£

ËùÒÔ¿ÉÒÔ¿´µ½ÔÚÔ´ÂëÖÐÕâÁ½¸ö·½·¨¶¼³öÏÖÔÚLockµÄ±£»¤¿éÖС£

ÏÂÃæÔÙÀ´ËµËµConcurrentLinkedQueue£¬ËüÊÇÒ»¸öÎÞËøµÄ²¢·¢Ḭ̈߳²È«µÄ¶ÓÁС£

¶Ô±ÈËø»úÖÆµÄʵÏÖ£¬Ê¹ÓÃÎÞËø»úÖÆµÄÄѵãÔÚÓÚÒª³ä·Ö¿¼ÂÇÏ̼߳äµÄЭµ÷¡£¼òµ¥µÄ˵¾ÍÊǶà¸öÏ̶߳ÔÄÚ²¿Êý¾Ý½á¹¹½øÐзÃÎÊʱ£¬Èç¹ûÆäÖÐÒ»¸öÏß³ÌÖ´ÐеÄÖÐ;ÒòΪһЩԭÒò³öÏÖ¹ÊÕÏ£¬ÆäËûµÄÏß³ÌÄܹ»¼ì²â²¢°ïÖúÍê³ÉʣϵIJÙ×÷¡£Õâ¾ÍÐèÒª°Ñ¶ÔÊý¾Ý½á¹¹µÄ²Ù×÷¹ý³Ì¾«Ï¸µÄ»®·Ö³É¶à¸ö״̬»ò½×¶Î£¬¿¼ÂÇÿ¸ö½×¶Î»ò״̬¶àÏ̷߳ÃÎÊ»á³öÏÖµÄÇé¿ö¡£

ConcurrentLinkedQueueÓÐÁ½¸övolatileµÄÏ̹߳²Ïí±äÁ¿£ºhead£¬tail¡£Òª±£Ö¤Õâ¸ö¶ÓÁеÄḬ̈߳²È«¾ÍÊDZ£Ö¤¶ÔÕâÁ½¸öNodeµÄÒýÓõķÃÎÊ£¨¸üУ¬²é¿´£©µÄÔ­×ÓÐԺͿɼûÐÔ£¬ÓÉÓÚvolatile±¾ÉíÄܹ»±£Ö¤¿É¼ûÐÔ£¬ËùÒÔ¾ÍÊÇ¶ÔÆäÐ޸ĵÄÔ­×ÓÐÔÒª±»±£Ö¤¡£

ÏÂÃæÍ¨¹ýoffer·½·¨µÄʵÏÖÀ´¿´¿´ÔÚÎÞËøÇé¿öÏÂÈçºÎ±£Ö¤Ô­×ÓÐÔ£º

public boolean offer(E e) {  
if (e == null)throw new NullPointerException();
Node<E> n = new Node<E>(e, null);
for (;;) {
Node<E> t = tail;
Node<E> s = t.getNext();
if (t == tail) { //------------------------------a
if (s == null) {//---------------------------b
if (t.casNext(s, n)) { //-------------------c
casTail(t, n); //------------------------d
return true;
}
} else {
casTail(t, s); //----------------------------e
}
}
}
}

´Ë·½·¨µÄÑ­»·ÄÚÊ×ÏÈ»ñµÃβָÕëºÍÆänextÖ¸ÏòµÄ¶ÔÏó£¬ÓÉÓÚtailºÍNodeµÄnext¾ùÊÇvolatileµÄ£¬ËùÒÔ±£Ö¤ÁË»ñµÃµÄ·Ö±ð¶¼ÊÇ×îеÄÖµ¡£

´úÂëa£ºt==tailÊÇ×îÉϲãµÄЭµ÷£¬Èç¹ûÆäËûÏ̸߳ıäÁËtailµÄÒýÓã¬Ôò˵Ã÷ÏÖÔÚ»ñµÃ²»ÊÇ×îеÄβָÕëÐèÒªÖØÐÂÑ­»·»ñµÃ×îеÄÖµ¡£

´úÂëb£ºs==nullµÄÅжϡ£¾²Ö¹×´Ì¬ÏÂtailµÄnextÒ»¶¨ÊÇÖ¸ÏònullµÄ£¬µ«ÊǶàÏß³ÌϵÄÁíÒ»¸ö״̬¾ÍÊÇÖмä̬£ºtailµÄÖ¸ÏòûÓиı䣬µ«ÊÇÆänextÒѾ­Ö¸ÏòеĽáµã£¬¼´Íê³ÉtailÒýÓøıäǰµÄ״̬£¬Õâʱºòs!=null¡£ÕâÀï¾ÍÊÇЭµ÷µÄµäÐÍÓ¦Óã¬Ö±½Ó½øÈë´úÂëeȥЭµ÷²ÎÓëÖмä̬µÄÏß³ÌÈ¥Íê³É×îºóµÄ¸üУ¬È»ºóÖØÐÂÑ­»·»ñµÃеÄtail¿ªÊ¼×Ô¼ºµÄÐÂÒ»´ÎµÄÈë¶Ó³¢ÊÔ¡£ÁíÍâÖµµÃ×¢ÒâµÄÊÇa,bÖ®¼ä£¬ÆäËûµÄÏ߳̿ÉÄÜ»á¸Ä±ätailµÄÖ¸Ïò£¬Ê¹µÃЭµ÷µÄ²Ù×÷ʧ°Ü¡£´ÓÕâ¸ö²½Öè¿ÉÒÔ¿´µ½ÎÞËøÊµÏֵĸ´ÔÓÐÔ¡£

´úÂëc£ºt.casNext(s, n)ÊÇÈë¶ÓµÄµÚÒ»²½£¬ÒòΪÈë¶ÓÐèÒªÁ½²½£º¸üÐÂNodeµÄnext£¬¸Ä±ätailµÄÖ¸Ïò¡£´úÂëc֮ǰ¿ÉÄÜ·¢ÉútailÒýÓÃÖ¸ÏòµÄ¸Ä±ä»òÕß½øÈë¸üеÄÖмä̬£¬ÕâÁ½ÖÖÇé¿ö¾ù»áʹµÃtÖ¸ÏòµÄÔªËØµÄnextÊôÐÔ±»Ô­×ӵĸı䣬²»ÔÙÖ¸Ïònull¡£Õâʱ´úÂëc²Ù×÷ʧ°Ü£¬ÖØÐ½øÈëÑ­»·¡£

´úÂëd£ºÕâÊÇÍê³É¸üеÄ×îºóÒ»²½ÁË£¬¾ÍÊǸüÐÂtailµÄÖ¸Ïò£¬×îÓÐÒâ˼µÄЭµ÷ÔÚÕâ¶ùÓÖÓÐÁËÌåÏÖ¡£´Ó´úÂë¿´casTail(t, n)²»¹ÜÊÇ·ñ³É¹¦¶¼»á½Ó×Å·µ»Øtrue±ê־ןüеijɹ¦¡£Ê×ÏÈÈç¹û³É¹¦Ôò±íÃ÷±¾Ïß³ÌÍê³ÉÁËÁ½²½µÄ¸üУ¬·µ»ØtrueÊÇÀíËùµ±È»µÄ£»Èç¹û casTail(t, n)²»³É¹¦ÄØ£¿ÒªÇå³þµÄÊÇÍê³É´úÂëcÔò´ú±íןüнøÈëÁËÖмä̬£¬´úÂëd²»³É¹¦ÔòÊÇtailµÄÖ¸Ïò±»ÆäËûÏ̸߳ı䡣Òâζ×ŶÔÓÚÆäËûµÄÏ̶߳øÑÔ£ºËüÃǵõ½µÄÊÇÖмä̬µÄ¸üУ¬s!=null£¬½øÈë´úÂëe°ïÖú±¾Ïß³ÌÖ´ÐÐ×îºóÒ»²½²¢ÇÒÏÈÓÚ±¾Ï̳߳ɹ¦¡£ÕâÑù±¾Ïß³ÌËäÈ»´úÂëdʧ°ÜÁË£¬µ«ÊÇÊÇÓÉÓÚ±ðµÄÏ̵߳ÄЭÖúÏÈÍê³ÉÁË£¬ËùÒÔ·µ»ØtrueÒ²¾ÍÀíËùµ±È»ÁË¡£

ͨ¹ý·ÖÎöÕâ¸öÈë¶ÓµÄ²Ù×÷£¬¿ÉÒÔÇåÎúµÄ¿´µ½ÎÞËøÊµÏÖµÄÿ¸ö²½ÖèºÍ״̬϶àÏß³ÌÖ®¼äµÄЭµ÷ºÍ¹¤×÷¡£

×¢£ºÉÏÃæÕâ´ó¶ÎÎÄ×Ö¿´ÆðÀ´ºÜÀÛ£¬ÏÈÄÜ¿´¶®¶àÉÙ¿´¶®¶àÉÙ£¬ÏÖÔÚ¿´²»¶®ÏȲ»¼±£¬ÏÂÃæ»¹»áÌáµ½Õâ¸öËã·¨£¬²¢ÇÒÓÃʾÒâͼ˵Ã÷£¬¾ÍÒ×¶®ºÜ¶àÁË¡£

ÔÚʹÓÃConcurrentLinkedQueueʱҪעÒ⣬Èç¹ûÖ±½ÓʹÓÃËüÌṩµÄº¯Êý£¬±ÈÈçadd»òÕßpoll·½·¨£¬ÕâÑùÎÒÃÇ×Ô¼º²»ÐèÒª×öÈκÎͬ²½¡£

µ«Èç¹ûÊÇ·ÇÔ­×Ó²Ù×÷£¬±ÈÈ磺

if(!queue.isEmpty()) {
queue.poll(obj);
}

ÎÒÃǺÜÄѱ£Ö¤£¬ÔÚµ÷ÓÃÁËisEmpty()Ö®ºó£¬poll()֮ǰ£¬Õâ¸öqueueûÓб»ÆäËûÏß³ÌÐ޸ġ£ËùÒÔ¶ÔÓÚÕâÖÖÇé¿ö£¬ÎÒÃÇ»¹ÊÇÐèÒª×Ô¼ºÍ¬²½£º

synchronized(queue) {
if(!queue.isEmpty()) {
queue.poll(obj);
}
}

×¢£ºÕâÖÖÐèÒª½øÐÐ×Ô¼ºÍ¬²½µÄÇé¿öÒªÊÓÇé¿ö¶ø¶¨£¬²»ÊÇÈκÎÇé¿ö϶¼ÐèÒªÕâÑù×ö¡£

ÁíÍ⻹˵һÏ£¬ConcurrentLinkedQueueµÄsize()ÊÇÒª±éÀúÒ»±é¼¯ºÏµÄ£¬ËùÒÔ¾¡Á¿Òª±ÜÃâÓÃsize¶ø¸ÄÓÃisEmpty()£¬ÒÔÃâÐÔÄܹýÂý¡£

×îºó×ܽáһϣ¬×èÈûËã·¨ÆäʵºÜºÃÀí½â£¬¼òµ¥µãÀí½â¾ÍÊǼÓËø£¬±ÈÈçÔÚBlockingQueueÖп´µ½µÄÄÇÑù£¬ÔÙÍùÇ°ÍÆµã£¬ÄǾÍÊÇsynchronized¡£Ïà±È¶øÑÔ£¬·Ç×èÈûËã·¨µÄÉè¼ÆºÍʵÏÖ¶¼ºÜÀ§ÄÑ£¬ÒªÍ¨¹ýµÍ¼¶µÄÔ­×ÓÐÔÀ´Ö§³Ö²¢·¢¡£ÏÂÃæ¾Í¼òÒªµÄ½éÉÜһϷÇ×èÈûËã·¨£¬ÒÔϲ¿·ÖµÄÄÚÈݲÎÕÕÁËһƪºÜ¾­µäµÄÎÄÕÂhttp://www.ibm.com/developerworks/cn/java/j-jtp04186/

×¢£ºÎÒ¾õµÃ¿ÉÒÔÕâÑùÀí½â£¬×èÈû¶ÔӦͬ²½£¬·Ç×èÈû¶ÔÓ¦²¢·¢¡£Ò²¿ÉÒÔ˵£ºÍ¬²½ÊÇ×èÈûģʽ£¬Òì²½ÊÇ·Ç×èÈûģʽ

¾Ù¸öÀý×ÓÀ´ËµÃ÷ʲôÊÇ·Ç×èÈûËã·¨£º·Ç×èÈûµÄ¼ÆÊýÆ÷

Ê×ÏÈ£¬Ê¹ÓÃͬ²½µÄḬ̈߳²È«µÄ¼ÆÊýÆ÷´úÂëÈçÏÂ

public finalclass Counter {
private long value =0;
public synchronizedlong getValue() {
return value;
}
public synchronizedlong increment() {
return ++value;
}
}

ÏÂÃæµÄ´úÂëÏÔʾÁËÒ»ÖÖ×î¼òµ¥µÄ·Ç×èÈûËã·¨£ºÊ¹Óà AtomicIntegerµÄcompareAndSet()£¨CAS·½·¨£©µÄ¼ÆÊýÆ÷¡£compareAndSet()·½·¨¹æ¶¨¡°½«Õâ¸ö±äÁ¿¸üÐÂΪÐÂÖµ£¬µ«ÊÇÈç¹û´ÓÎÒÉϴο´µ½Õâ¸ö±äÁ¿Ö®ºóÆäËûÏß³ÌÐÞ¸ÄÁËËüµÄÖµ£¬ÄÇô¸üоÍʧ°Ü¡±

public class NonblockingCounter {
private AtomicInteger value;//Ç°ÃæÌáµ½¹ý£¬AtomicIntegerÀàÊÇÒÔÔ­×ӵķ½Ê½²Ù×÷ÕûÐͱäÁ¿¡£
public int getValue() {
return value.get();
}
public int increment() {
int v;
do {
v = value.get();
while (!value.compareAndSet(v, v +1));
return v + 1;
}
}

·Ç×èÈû°æ±¾Ïà¶ÔÓÚ»ùÓÚËøµÄ°æ±¾Óм¸¸öÐÔÄÜÓÅÊÆ¡£Ê×ÏÈ£¬ËüÓÃÓ²¼þµÄÔ­ÉúÐÎ̬´úÌæ JVM µÄËø¶¨´úÂë·¾¶£¬´Ó¶øÔÚ¸üϸµÄÁ£¶È²ã´ÎÉÏ£¨¶ÀÁ¢µÄÄÚ´æÎ»Ö㩽øÐÐͬ²½£¬Ê§°ÜµÄÏß³ÌÒ²¿ÉÒÔÁ¢¼´ÖØÊÔ£¬¶ø²»»á±»¹ÒÆðºóÖØÐµ÷¶È¡£¸üϸµÄÁ£¶È½µµÍÁËÕùÓõĻú»á£¬²»ÓÃÖØÐµ÷¶È¾ÍÄÜÖØÊÔµÄÄÜÁ¦Ò²½µµÍÁËÕùÓõijɱ¾¡£¼´Ê¹ÓÐÉÙÁ¿Ê§°ÜµÄ CAS ²Ù×÷£¬ÕâÖÖ·½·¨ÈÔÈ»»á±ÈÓÉÓÚËøÕùÓÃÔì³ÉµÄÖØÐµ÷¶È¿ìµÃ¶à¡£

NonblockingCounter Õâ¸öʾÀý¿ÉÄܼòµ¥ÁËЩ£¬µ«ÊÇËüÑÝʾÁËËùÓзÇ×èÈûËã·¨µÄÒ»¸ö»ù±¾ÌØÕ÷¡ª¡ªÓÐЩËã·¨²½ÖèµÄÖ´ÐÐÊÇҪðÏյģ¬ÒòΪ֪µÀÈç¹û CAS ²»³É¹¦¿ÉÄܲ»µÃ²»ÖØ×ö¡£·Ç×èÈûË㷨ͨ³£½Ð×÷ÀÖ¹ÛËã·¨£¬ÒòΪËüÃǼÌÐø²Ù×÷µÄ¼ÙÉèÊDz»»áÓиÉÈÅ¡£Èç¹û·¢ÏÖ¸ÉÈÅ£¬¾Í»á»ØÍ˲¢ÖØÊÔ¡£ÔÚ¼ÆÊýÆ÷µÄʾÀýÖУ¬Ã°ÏյIJ½ÖèÊǵÝÔö¡ª¡ªËü¼ìË÷¾ÉÖµ²¢ÔÚ¾ÉÖµÉϼÓÒ»£¬Ï£ÍûÔÚ¼ÆËã¸üÐÂÆÚ¼äÖµ²»»á±ä»¯¡£Èç¹ûËüµÄÏ£ÍûÂä¿Õ£¬¾Í»áÔٴμìË÷Öµ£¬²¢ÖØ×öµÝÔö¼ÆËã¡£

ÔÙÀ´Ò»¸öÀý×Ó£¬Michael-Scott ·Ç×èÈû¶ÓÁÐËã·¨µÄ²åÈë²Ù×÷£¬ConcurrentLinkedQueue ¾ÍÊÇÓÃÕâ¸öË㷨ʵÏֵģ¬ÏÖÔÚÀ´½áºÏʾÒâͼ·ÖÎöһϣ¬ºÜÃ÷ÀÊ£º

public class LinkedQueue <E> {  
private staticclass Node <E> {
final E item;
final AtomicReference<Node<E>> next;
Node(E item, Node<E> next) {
this.item = item;
this.next = new AtomicReference<Node<E>>(next);
}
}
private AtomicReference<Node<E>> head= new AtomicReference<Node<E>>(new Node<E>(null,null));
private AtomicReference<Node<E>> tail = head;
public boolean put(E item) {
Node<E> newNode = new Node<E>(item,null);
while (true) {
Node<E> curTail = tail.get();
Node<E> residue = curTail.next.get();
if (curTail == tail.get()) {
if (residue == null)/* A */ {
if (curTail.next.compareAndSet(null, newNode))/* C */ {
tail.compareAndSet(curTail, newNode) /* D */ ;
return true;
}
} else {
tail.compareAndSet(curTail, residue) /* B */;
}
}
}
}
}

Õâ´úÂëÍêÈ«¾ÍÊÇConcurrentLinkedQueue Ô´Âë¡£

²åÈëÒ»¸öÔªËØÉæ¼°Í·Ö¸ÕëºÍβָÕëÁ½¸öÖ¸Õë¸üУ¬ÕâÁ½¸ö¸üж¼ÊÇͨ¹ý CAS ½øÐеģº´Ó¶ÓÁе±Ç°µÄ×îºó½Úµã£¨C£©Á´½Óµ½Ð½ڵ㣬²¢°ÑβָÕëÒÆ¶¯µ½ÐµÄ×îºóÒ»¸ö½Úµã£¨D£©¡£Èç¹ûµÚÒ»²½Ê§°Ü£¬ÄÇô¶ÓÁеÄ״̬²»±ä£¬²åÈëÏ̻߳á¼ÌÐøÖØÊÔ£¬Ö±µ½³É¹¦¡£Ò»µ©²Ù×÷³É¹¦£¬²åÈë±»µ±³ÉÉúЧ£¬ÆäËûÏ߳̾ͿÉÒÔ¿´µ½Ð޸ġ£»¹ÐèÒª°ÑβָÕëÒÆ¶¯µ½Ð½ڵãµÄλÖÃÉÏ£¬µ«ÊÇÕâÏ×÷¿ÉÒÔ¿´³ÉÊÇ ¡°ÇåÀí¹¤×÷¡±£¬ÒòΪÈκδ¦ÔÚÕâÖÖÇé¿öϵÄÏ̶߳¼¿ÉÒÔÅжϳöÊÇ·ñÐèÒªÕâÖÖÇåÀí£¬Ò²ÖªµÀÈçºÎ½øÐÐÇåÀí¡£

¶ÓÁÐ×ÜÊÇ´¦ÓÚÁ½ÖÖ״̬֮һ£ºÕý³£×´Ì¬£¨»ò³Æ¾²Ö¹×´Ì¬£¬Í¼ 1 ºÍ ͼ 3£©»òÖмä״̬£¨Í¼ 2£©¡£ÔÚ²åÈë²Ù×÷֮ǰºÍµÚ¶þ¸ö CAS£¨D£©³É¹¦Ö®ºó£¬¶ÓÁд¦ÔÚ¾²Ö¹×´Ì¬£»ÔÚµÚÒ»¸ö CAS£¨C£©³É¹¦Ö®ºó£¬¶ÓÁд¦ÔÚÖмä״̬¡£ÔÚ¾²Ö¹×´Ì¬Ê±£¬Î²Ö¸ÕëÖ¸ÏòµÄÁ´½Ó½ÚµãµÄ next ×Ö¶Î×ÜΪ null£¬¶øÔÚÖмä״̬ʱ£¬Õâ¸ö×Ö¶ÎΪ·Ç null¡£ÈκÎÏß³Ìͨ¹ý±È½Ï tail.next ÊÇ·ñΪ null£¬¾Í¿ÉÒÔÅжϳö¶ÓÁеÄ״̬£¬ÕâÊÇÈÃÏ߳̿ÉÒÔ°ïÖúÆäËûÏß³Ì ¡°Íê³É¡± ²Ù×÷µÄ¹Ø¼ü¡£

ÉÏͼÏÔʾµÄÊÇ£ºÓÐÁ½¸öÔªËØ£¬´¦ÔÚ¾²Ö¹×´Ì¬µÄ¶ÓÁÐ

²åÈë²Ù×÷ÔÚ²åÈëÐÂÔªËØ£¨A£©Ö®Ç°£¬Ïȼì²é¶ÓÁÐÊÇ·ñ´¦ÔÚÖмä״̬¡£Èç¹ûÊÇÔÚÖмä״̬£¬ÄÇô¿Ï¶¨ÓÐÆäËûÏß³ÌÒѾ­´¦ÔÚÔªËØ²åÈëµÄÖÐ;£¬ÔÚ²½Ö裨C£©ºÍ£¨D£©Ö®¼ä¡£²»±ØµÈºòÆäËûÏß³ÌÍê³É£¬µ±Ç°Ï߳̾ͿÉÒÔ ¡°°ïÖú¡± ËüÍê³É²Ù×÷£¬°ÑβָÕëÏòÇ°ÒÆ¶¯£¨B£©¡£Èç¹ûÓбØÒª£¬Ëü»¹»á¼ÌÐø¼ì²éβָÕë²¢ÏòÇ°ÒÆ¶¯Ö¸Õ룬ֱµ½¶ÓÁд¦ÓÚ¾²Ö¹×´Ì¬£¬ÕâʱËü¾Í¿ÉÒÔ¿ªÊ¼×Ô¼ºµÄ²åÈëÁË¡£

µÚÒ»¸ö CAS£¨C£©¿ÉÄÜÒòΪÁ½¸öÏ߳̾ºÕù·ÃÎʶÓÁе±Ç°µÄ×îºóÒ»¸öÔªËØ¶øÊ§°Ü£»ÔÚÕâÖÖÇé¿öÏ£¬Ã»Óз¢ÉúÐ޸ģ¬Ê§È¥ CAS µÄÏ̻߳áÖØÐÂ×°ÈëβָÕë²¢Ôٴγ¢ÊÔ¡£Èç¹ûµÚ¶þ¸ö CAS£¨D£©Ê§°Ü£¬²åÈëÏ̲߳»ÐèÒªÖØÊÔ ¡ª¡ª ÒòΪÆäËûÏß³ÌÒѾ­ÔÚ²½Ö裨B£©ÖÐÌæËüÍê³ÉÁËÕâ¸ö²Ù×÷£¡

ÉÏͼÏÔʾµÄÊÇ£º´¦ÔÚ²åÈëÖмä״̬µÄ¶ÓÁУ¬ÔÚÐÂÔªËØ²åÈëÖ®ºó£¬Î²Ö¸Õë¸üÐÂ֮ǰ

ÉÏͼÏÔʾµÄÊÇ£ºÔÚβָÕë¸üк󣬶ÓÁÐÖØÐ´¦ÔÚ¾²Ö¹×´Ì¬

   
2576 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Java΢·þÎñÐÂÉú´úÖ®Nacos
ÉîÈëÀí½âJavaÖеÄÈÝÆ÷
JavaÈÝÆ÷Ïê½â
Java´úÂëÖÊÁ¿¼ì²é¹¤¾ß¼°Ê¹Óð¸Àý
Ïà¹ØÎĵµ

JavaÐÔÄÜÓÅ»¯
Spring¿ò¼Ü
SSM¿ò¼Ü¼òµ¥¼òÉÜ
´ÓÁ㿪ʼѧjava±à³Ì¾­µä
Ïà¹Ø¿Î³Ì

¸ßÐÔÄÜJava±à³ÌÓëϵͳÐÔÄÜÓÅ»¯
JavaEE¼Ü¹¹¡¢ Éè¼ÆÄ£Ê½¼°ÐÔÄܵ÷ÓÅ
Java±à³Ì»ù´¡µ½Ó¦Óÿª·¢
JAVAÐéÄâ»úÔ­ÀíÆÊÎö
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

Java ÖеÄÖÐÎıàÂëÎÊÌâ
Java»ù´¡ÖªÊ¶µÄÈýÊ®¸ö¾­µäÎÊ´ð
Íæ×ª Java Web Ó¦Óÿª·¢
ʹÓÃSpring¸üºÃµØ´¦ÀíStruts
ÓÃEclipse¿ª·¢iPhone WebÓ¦ÓÃ
²å¼þϵͳ¿ò¼Ü·ÖÎö

Struts+Spring+Hibernate
»ùÓÚJ2EEµÄWeb 2.0Ó¦Óÿª·¢
J2EEÉè¼ÆÄ£Ê½ºÍÐÔÄܵ÷ÓÅ
Java EE 5ÆóÒµ¼¶¼Ü¹¹Éè¼Æ
Javaµ¥Ôª²âÊÔ·½·¨Óë¼¼Êõ
Java±à³Ì·½·¨Óë¼¼Êõ

Struts+Spring+Hibernate/EJB+ÐÔÄÜÓÅ»¯
»ªÏÄ»ù½ð ActiveMQ Ô­ÀíÓë¹ÜÀí
ijÃñº½¹«Ë¾ Java»ù´¡±à³Ìµ½Ó¦Óÿª·¢
ij·çµç¹«Ë¾ Java Ó¦Óÿª·¢Æ½Ì¨ÓëÇ¨ÒÆ
ÈÕÕÕ¸Û J2EEÓ¦Óÿª·¢¼¼Êõ¿ò¼ÜÓëʵ¼ù
ij¿ç¹ú¹«Ë¾ ¹¤×÷Á÷¹ÜÀíJBPM
¶«·½º½¿Õ¹«Ë¾ ¸ß¼¶J2EE¼°ÆäÇ°ÑØ¼¼Êõ