ºìÁªLinuxÃÅ»§
Linux°ïÖú

¹ØÓÚ½â¾ö Java ±à³ÌÓïÑÔÏß³ÌÎÊÌâµÄ½¨Ò飨2£©

·¢²¼Ê±¼ä:2006-05-03 19:11:35À´Ô´:ºìÁª×÷Õß:ÌìɽÀÏͯ
ÔÚ¡¶Taming Java Threads¡·µÄµÚ°ËÕÂÖУ¬ÎÒ¸ø³öÁËÒ»¸ö·þÎñÆ÷¶ËµÄ socket ´¦Àí³ÌÐò£¬×÷ΪÏ̳߳صÄÀý×Ó¡£ËüÊǹØÓÚʹÓÃÏ̳߳صÄÈÎÎñµÄÒ»¸öºÃÀý×Ó¡£Æä»ù±¾Ë¼Â·ÊDzúÉúÒ»¸ö¶ÀÁ¢¶ÔÏó£¬ËüµÄÈÎÎñÊǼà¿ØÒ»¸ö·þÎñÆ÷¶ËµÄ socket¡£Ã¿µ±Ò»¸ö¿Í»§»úÁ¬½Óµ½·þÎñÆ÷ʱ£¬·þÎñÆ÷¶ËµÄ¶ÔÏó»á´Ó³ØÖÐץȡһ¸öÔ¤ÏÈ´´½¨µÄ˯ÃßỊ̈߳¬²¢°Ñ´ËÏß³ÌÉèÖÃΪ·þÎñÓÚ¿Í»§¶ËÁ¬½Ó¡£socket ·þÎñÆ÷»á²ú³öÒ»¸ö¶îÍâµÄ¿Í»§·þÎñỊ̈߳¬µ«Êǵ±Á¬½Ó¹Ø±Õʱ£¬ÕâЩ¶îÍâµÄÏ߳̽«±»É¾³ý¡£ÊµÏÖ socket ·þÎñÆ÷µÄÍƼöÓï·¨ÈçÏ£º
public $pooled(10) $task Client_handler
{
PrintWriter log = new PrintWriter( System.out );

public asynchronous void handle( Socket connection_to_the_client )
{
log.println("writing");

// client-handling code goes here. Every call to
// handle() is executed on its own thread, but 10
// threads are pre-created for this purpose. Additional
// threads are created on an as-needed basis, but are
// discarded when handle() returns.
}
}

$task Socket_server
{
ServerSocket server;
Client_handler client_handlers = new Client_handler();

public Socket_server( int port_number )
{ server = new ServerSocket(port_number);
}

public $asynchronous listen(Client_handler client)
{
// This method is executed on its own thread.

while( true )
{ client_handlers.handle( server.accept() );
}
}
}

//...

Socket_server = new Socket_server( the_port_number );
server.listen()




Socket_server ¶ÔÏóʹÓÃÒ»¸ö¶ÀÁ¢µÄºǫ́Ï̴߳¦ÀíÒì²½µÄ listen() ÇëÇó£¬Ëü·â×° socket µÄ¡°½ÓÊÜ¡±Ñ­»·¡£µ±Ã¿¸ö¿Í»§¶ËÁ¬½Óʱ£¬listen()
ÇëÇóÒ»¸ö Client_handler ͨ¹ýµ÷Óà handle() À´´¦ÀíÇëÇó¡£Ã¿¸ö handle() ÇëÇóÔÚËüÃÇ×Ô¼ºµÄÏß³ÌÖÐÖ´ÐУ¨ÒòΪÕâÊÇÒ»¸ö $pooled ÈÎÎñ)¡£




×¢Ò⣬ÿ¸ö´«Ë͵½ $pooled $task µÄÒì²½ÏûϢʵ¼ÊÉ϶¼Ê¹ÓÃËüÃÇ×Ô¼ºµÄÏß³ÌÀ´´¦Àí¡£µäÐÍÇé¿öÏ£¬ÓÉÓÚÒ»¸ö
$pooled $task ÓÃÓÚʵÏÖÒ»¸ö×ÔÖ÷²Ù×÷£»ËùÒÔ¶ÔÓÚ½â¾öÓë·ÃÎÊ״̬±äÁ¿ÓйصÄDZÔÚµÄͬ²½ÎÊÌ⣬×îºÃµÄ½â¾ö·½·¨ÊÇÔÚ
$asynchronous ·½·¨ÖÐʹÓà this ÊÇÖ¸ÏòµÄ¶ÔÏóµÄÒ»¸ö¶ÀÓи±±¾¡£Õâ¾ÍÊÇ˵£¬µ±ÏòÒ»¸ö
$pooled $task ·¢ËÍÒ»¸öÒì²½ÇëÇóʱ£¬½«Ö´ÐÐÒ»¸ö clone() ²Ù×÷£¬²¢ÇÒ´Ë·½·¨µÄ
this Ö¸Õë»áÖ¸Ïò´Ë¿Ë¡¶ÔÏó¡£Ïß³ÌÖ®¼äµÄͨÐÅ¿Éͨ¹ý¶Ô static ÇøµÄͬ²½·ÃÎÊʵÏÖ¡£

¸Ä½ø synchronized

ËäÈ»ÔÚ¶àÊýÇé¿öÏ£¬ $task Ïû³ýÁËͬ²½²Ù×÷µÄÒªÇ󣬵«ÊDz»ÊÇËùÓеĶàÏß³Ìϵͳ¶¼ÓÃÈÎÎñÀ´ÊµÏÖ¡£ËùÒÔ£¬»¹ÐèÒª¸Ä½øÏÖÓеÄÏß³ÌÄ£¿é¡£
synchronized ¹Ø¼ü×ÖÓÐÏÂÁÐȱµã£º


ÎÞ·¨Ö¸¶¨Ò»¸ö³¬Ê±Öµ¡£

ÎÞ·¨ÖжÏÒ»¸öÕýÔڵȴýÇëÇóËøµÄÏ̡߳£

ÎÞ·¨°²È«µØÇëÇó¶à¸öËø ¡£(¶à¸öËøÖ»ÄÜÒÔÒÀ´ÎÐò»ñµÃ¡£)


½â¾öÕâЩÎÊÌâµÄ°ì·¨ÊÇ£ºÀ©Õ¹ synchronized µÄÓï·¨£¬Ê¹ËüÖ§³Ö¶à¸ö²ÎÊýºÍÄܽÓÊÜÒ»¸ö³¬Ê±ËµÃ÷£¨ÔÚÏÂÃæµÄÀ¨»¡ÖÐÖ¸¶¨£©¡£ÏÂÃæÊÇÎÒÏ£ÍûµÄÓï·¨£º


synchronized(x && y && z)
»ñµÃ x¡¢y ºÍ z
¶ÔÏóµÄËø¡£



synchronized(x || y || z)
»ñµÃ x¡¢y »ò z
¶ÔÏóµÄËø¡£







synchronized( (x && y ) || z)
¶ÔÓÚÇ°Ãæ´úÂëµÄһЩÀ©Õ¹¡£



synchronized(...)[1000]
ÉèÖà 1 Ã볬ʱÒÔ»ñµÃÒ»¸öËø¡£



synchronized[1000] f(){...}
ÔÚ½øÈë f() º¯Êýʱ»ñµÃ this µÄËø£¬µ«¿ÉÓÐ 1 Ã볬ʱ¡£





TimeoutException ÊÇ RuntimeException ÅÉÉúÀ࣬ËüÔڵȴý³¬Ê±ºó¼´±»Å׳ö¡£

³¬Ê±ÊÇÐèÒªµÄ£¬µ«»¹²»×ãÒÔʹ´úÂëǿ׳¡£Äú»¹ÐèÒª¾ß±¸´ÓÍⲿÖÐÖ¹ÇëÇóËøµÈ´ýµÄÄÜÁ¦¡£ËùÒÔ£¬µ±ÏòÒ»¸öµÈ´ýËøµÄÏ̴߳«ËÍÒ»¸ö
interrupt() ·½·¨ºó£¬´Ë·½·¨Ó¦Å׳öÒ»¸ö SynchronizationException ¶ÔÏ󣬲¢ÖжϵȴýµÄÏ̡߳£Õâ¸öÒì³£Ó¦ÊÇ RuntimeException
µÄÒ»¸öÅÉÉúÀ࣬ÕâÑù²»±ØÌرð´¦ÀíËü¡£

¶Ô synchronized Óï·¨ÕâЩÍƼöµÄ¸ü¸Ä·½·¨µÄÖ÷ÒªÎÊÌâÊÇ£¬ËüÃÇÐèÒªÔÚ¶þ½øÖÆ´úÂ뼶ÉÏÐ޸ġ£¶øÄ¿Ç°ÕâЩ´úÂëʹÓýøÈë¼à¿Ø(enter-monitor)ºÍÍ˳ö¼à¿Ø(exit-monitor)Ö¸ÁîÀ´ÊµÏÖ
synchronized¡£¶øÕâЩָÁîûÓвÎÊý£¬ËùÒÔÐèÒªÀ©Õ¹¶þ½øÖÆ´úÂëµÄ¶¨ÒåÒÔÖ§³Ö¶à¸öËø¶¨ÇëÇó¡£µ«ÊÇÕâÖÖÐ޸IJ»»á±ÈÔÚ
Java 2 ÖÐÐÞ¸Ä Java ÐéÄâ»úµÄ¸üÇáËÉ£¬µ«ËüÊÇÏòϼæÈÝÏÖ´æµÄ Java ´úÂë¡£

ÁíÒ»¸ö¿É½â¾öµÄÎÊÌâÊÇ×î³£¼ûµÄËÀËøÇé¿ö£¬ÔÚÕâÖÖÇé¿öÏ£¬Á½¸öÏ̶߳¼Ôڵȴý¶Ô·½Íê³Éij¸ö²Ù×÷¡£ÉèÏëÏÂÃæµÄÒ»¸öÀý×Ó£¨¼ÙÉèµÄ£©£º


class Broken
{ Object lock1 = new Object();
Object lock2 = new Object();

void a()
{ synchronized( lock1 )
{ synchronized( lock2 )
{ // do something
}
}
}

void b()
{ synchronized( lock2 )
{ synchronized( lock1 )
{ // do something
}
}
}




ÉèÏëÒ»¸öÏ̵߳÷Óà a()£¬µ«ÔÚ»ñµÃ¡¡lock1Ö®ºóÔÚ»ñµÃ lock2 ֮ǰ±»°þ¶áÔËÐÐȨ¡£
µÚ¶þ¸öÏ߳̽øÈëÔËÐУ¬µ÷Óà b()£¬»ñµÃÁË lock2£¬µ«ÊÇÓÉÓÚµÚÒ»¸öÏß³ÌÕ¼Óà lock1£¬ËùÒÔËüÎÞ·¨»ñµÃ
lock1£¬ËùÒÔËüËæºó´¦Óڵȴý״̬¡£´ËʱµÚÒ»¸öÏ̱߳»»½ÐÑ£¬ËüÊÔͼ»ñµÃ lock2£¬µ«ÊÇÓÉÓÚ±»µÚ¶þ¸öÏß³ÌÕ¼¾Ý£¬ËùÒÔÎÞ·¨»ñµÃ¡£
´Ëʱ³öÏÖËÀËø¡£ÏÂÃæµÄ synchronize-on-multiple-objects µÄÓï·¨¿É½â¾öÕâ¸öÎÊÌ⣺




//...
void a()
{ synchronized( lock1 && lock2 )
{
}
}

void b()
{ synchronized( lock2 && lock3 )
{
}
}





±àÒëÆ÷(»òÐéÄâ»ú)»áÖØÐÂÅÅÁÐÇëÇóËøµÄ˳Ðò£¬Ê¹ lock1 ×ÜÊDZ»Ê×ÏÈ»ñµÃ£¬Õâ¾ÍÏû³ýÁËËÀËø¡£




µ«ÊÇ£¬ÕâÖÖ·½·¨¶Ô¶àÏ̲߳»Ò»¶¨×ܳɹ¦£¬ËùÒÔµÃÌṩһЩ·½·¨À´×Ô¶¯´òÆÆËÀËø¡£Ò»¸ö¼òµ¥µÄ°ì·¨¾ÍÊÇÔڵȴýµÚ¶þ¸öËøʱ³£ÊÍ·ÅÒÑ»ñµÃµÄËø¡£Õâ¾ÍÊÇ˵£¬Ó¦²ÉÈ¡Èçϵĵȴý·½Ê½£¬¶ø²»ÊÇÓÀÔ¶µÈ´ý£º




while( true )
{ try
{ synchronized( some_lock )[10]
{ // do the work here.
break;
}
}
catch( TimeoutException e )
{ continue;
}
}




Èç¹ûµÈ´ýËøµÄÿ¸ö³ÌÐòʹÓò»Í¬µÄ³¬Ê±Öµ£¬¾Í¿É´òÆÆËÀËø¶øÆäÖÐÒ»¸öÏ߳̾ͿÉÔËÐС£ÎÒ½¨ÒéÓÃÒÔϵÄÓï·¨À´È¡´úÇ°ÃæµÄ´úÂ룺




synchronized( some_lock )[]
{ // do the work here.
}




synchronized Óï¾ä½«ÓÀÔ¶µÈ´ý£¬µ«ÊÇËüʱ³£»á·ÅÆúÒÑ»ñµÃµÄËøÒÔ´òÆÆDZÔÚµÄËÀËø¿ÉÄÜ¡£ÔÚÀíÏëÇé¿öÏ£¬Ã¿¸öÖظ´µÈ´ýµÄ³¬Ê±Öµ±ÈÇ°Ò»¸öÏà²îÒ»Ëæ»úÖµ¡£


¸Ä½ø wait() ºÍ notify()


wait()/notify() ϵͳҲÓÐһЩÎÊÌ⣺


ÎÞ·¨¼ì²â wait() ÊÇÕý³£·µ»Ø»¹ÊÇÒò³¬Ê±·µ»Ø¡£

ÎÞ·¨Ê¹Óô«Í³Ìõ¼þ±äÁ¿À´ÊµÏÖ´¦ÓÚÒ»¸ö¡°Ðźš±(signaled)״̬¡£

Ì«ÈÝÒ×·¢ÉúǶÌ׵ļà¿Ø(monitor)Ëø¶¨¡£

³¬Ê±¼ì²âÎÊÌâ¿ÉÒÔͨ¹ýÖØж¨Òå wait() ʹËü·µ»ØÒ»¸ö
boolean ±äÁ¿ (¶ø²»ÊÇ void ) À´½â¾ö¡£Ò»¸ö true
·µ»Øֵָʾһ¸öÕý³£·µ»Ø£¬¶ø false ָʾÒò³¬Ê±·µ»Ø¡£


»ùÓÚ״̬µÄÌõ¼þ±äÁ¿µÄ¸ÅÄîÊǺÜÖØÒªµÄ¡£Èç¹û´Ë±äÁ¿±»ÉèÖóÉ
false ״̬£¬ÄÇôµÈ´ýµÄÏ߳̽«Òª±»×è¶Ï£¬Ö±µ½´Ë±äÁ¿½øÈë
true ״̬£»Èκεȴý true µÄÌõ¼þ±äÁ¿µÄµÈ´ýÏ̻߳ᱻ×Ô¶¯ÊÍ·Å¡£
(ÔÚÕâÖÖÇé¿öÏ£¬wait() µ÷Óò»»á·¢Éú×è¶Ï¡£)¡£Í¨¹ýÈçÏÂÀ©Õ¹
notify() µÄÓï·¨£¬¿ÉÒÔÖ§³ÖÕâ¸ö¹¦ÄÜ£º


notify();
ÊÍ·ÅËùÓеȴýµÄỊ̈߳¬¶ø²»¸Ä±äÆäÏÂÃæµÄÌõ¼þ±äÁ¿µÄ״̬¡£



notify(true);
°ÑÌõ¼þ±äÁ¿µÄ״̬ÉèÖÃΪ true ²¢ÊÍ·ÅÈκεȴýµÄ½ø³Ì¡£Æäºó¶ÔÓÚ
wait() µÄµ÷Óò»»á·¢Éú×è¶Ï¡£



notify(false);
°ÑÌõ¼þ±äÁ¿µÄ״̬ÉèÖÃΪ false (Æäºó¶ÔÓÚ wait() µÄµ÷ÓûᷢÉú×è¶Ï)¡£





ǶÌ×¼à¿ØËø¶¨ÎÊÌâ·Ç³£Âé·³£¬ÎÒ²¢Ã»Óмòµ¥µÄ½â¾ö°ì·¨¡£Ç¶Ì×¼à¿ØËø¶¨ÊÇÒ»ÖÖËÀËøÐÎʽ£¬µ±Ä³¸öËøµÄÕ¼ÓÐÏß³ÌÔÚ¹ÒÆðÆä×ÔÉí֮ǰ²»ÊÍ·ÅËøʱ£¬»á·¢ÉúÕâÖÖǶÌ×¼à¿Ø·âËø¡£
ÏÂÃæÊÇ´ËÎÊÌâµÄÒ»¸öÀý×Ó£¨»¹ÊǼÙÉèµÄ£©£¬µ«ÊÇʵ¼ÊµÄÀý×ÓÊǷdz£¶àµÄ£º


class Stack
{
LinkedList list = new LinkedList();

public synchronized void push(Object x)
{ synchronized(list)
{ list.addLast( x );
notify();
}
}

public synchronized Object pop()
{ synchronized(list)
{ if( list.size() <= 0 )
wait();
return list.removeLast();
}
}

}




´ËÀýÖУ¬ÔÚ get() ºÍ put() ²Ù×÷ÖÐÉæ¼°Á½¸öËø£ºÒ»¸öÔÚ Stack ¶ÔÏóÉÏ£¬ÁíÒ»¸öÔÚ LinkedList
¶ÔÏóÉÏ¡£ÏÂÃæÎÒÃÇ¿¼Âǵ±Ò»¸öÏß³ÌÊÔͼµ÷ÓÃÒ»¸ö¿ÕÕ»µÄ pop() ²Ù×÷ʱµÄÇé¿ö¡£´ËÏ̻߳ñµÃÕâÁ½¸öËø£¬È»ºóµ÷Óà wait() ÊÍ·Å Stack ¶ÔÏóÉÏ
µÄËø£¬µ«ÊÇûÓÐÊÍ·ÅÔÚ list ÉϵÄËø¡£Èç¹û´ËʱµÚ¶þ¸öÏß³ÌÊÔͼÏò¶ÑÕ»ÖÐѹÈëÒ»¸ö¶ÔÏó£¬Ëü»áÔÚ synchronized(list) Óï¾äÉÏÓÀÔ¶¹ÒÆð£¬
¶øÇÒÓÀÔ¶²»»á±»ÔÊÐíѹÈëÒ»¸ö¶ÔÏó¡£ÓÉÓÚµÚÒ»¸öÏ̵߳ȴýµÄÊÇÒ»¸ö·Ç¿ÕÕ»£¬ÕâÑù¾Í»á·¢ÉúËÀËø¡£Õâ¾ÍÊÇ˵£¬µÚÒ»¸öÏß³ÌÓÀÔ¶ÎÞ·¨´Ó wait() ·µ»Ø£¬ÒòΪÓÉÓÚËüÕ¼¾Ý×ÅËø£¬¶øµ¼Öµڶþ¸öÏß³ÌÓÀÔ¶ÎÞ·¨ÔËÐе½ notify() Óï¾ä¡£




ÔÚÕâ¸öÀý×ÓÖУ¬ÓкܶàÃ÷ÏԵİ취À´½â¾öÎÊÌ⣺ÀýÈ磬¶ÔÈκεķ½·¨¶¼Ê¹ÓÃͬ²½¡£µ«ÊÇÔÚÕæʵÊÀ½çÖУ¬½â¾ö·½·¨Í¨³£²»ÊÇÕâô¼òµ¥¡£


Ò»¸ö¿ÉÐеķ½·¨ÊÇ£¬ÔÚ wait() Öа´ÕÕ·´Ë³ÐòÊͷŵ±Ç°Ï̻߳ñÈ¡µÄËùÓÐËø£¬È»ºóµ±µÈ´ýÌõ¼þÂú×ãºó£¬ÖØа´Ô­Ê¼»ñȡ˳ÐòÈ¡µÃËüÃÇ¡£
µ«ÊÇ£¬ÎÒÄÜÏëÏó³öÀûÓÃÕâÖÖ·½Ê½µÄ´úÂë¶ÔÓÚÈËÃÇÀ´Ëµ¼òÖ±ÎÞ·¨Àí½â£¬ËùÒÔÎÒÈÏΪËü²»ÊÇÒ»¸öÕæÕý¿ÉÐеķ½·¨¡£Èç¹ûÄúÓкõķ½·¨£¬Çë¸øÎÒ·¢ e-mail¡£


ÎÒҲϣÍûÄܵȵ½ÏÂÊö¸´ÔÓÌõ¼þ±»ÊµÏÖµÄÒ»Ìì¡£ÀýÈ磺

(a && (b || c)).wait();
ÆäÖÐ a¡¢b ºÍ c ÊÇÈÎÒâ¶ÔÏó¡£
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 0 ÌõÆÀÂÛ