ÁÖÀÇ: º»¹®¼´Â ¸¶ÀÌÅ©·Î¼ÒÇÁÆ®¿þ¾î 2002~11¿ù,12¿ùÈ£¿¡ ¼ÛÁöÈÆ´ÔÀÌ ±â°íÇÑ ±Û·Î½á º»ÀÎÀÇ µ¿ÀǾøÀÌ ¹«´Ü ¹èÆ÷ÇÏ´Â °ÍÀ» ±ÝÁöÇÔ. ¸¸¾à ±ÛÀ» ´Ù¸¥ °÷¿¡ Æ÷½ºÆÃÇÏ·Á ÇÒ °æ¿ì ¹Ýµå½Ã °ÁÂÀÇ URL ¸µÅ©¸¦ »ç¿ëÇØ¾ßÇÔ.
J2SDK1.4¿¡ Ãß°¡µÈ nio·Î ºñµ¿±â½Ä °í°¡¿ë¼º ¼¹ö ¸¸µé±â
¸¸µçÀÌ: ¼ÛÁöÈÆ
¼Ò¼Ó:
JavaCafe ºÎ½Ã¼¥
email:
johnleen@hanmail.net
±âÁ¸ÀÇ ±â¼ú¿¡ ´ëÀÀÇØ »õ·Î¿î ±â¼úÀÌ ³ª¿Â´Ù´Â °ÍÀº ±âÁ¸ ±â¼ú¿¡ ¾î¶² ¹®Á¦Á¡ ÀÖ°í »õ·Î¿î ±â¼úÀÌ ±×·± ¹®Á¦Á¡À» ÇØ°á ¶Ç´Â ¾î´À Á¤µµ ±Øº¹ÇÒ ¼ö ÀÖ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. ÀÌ ±ÛÀº ±âÁ¸ io¸¦ ÀÌ¿ëÇØ ¼¹ö ÇÁ·Î±×·¥À» ÇÒ °æ¿ì ¾î¶² ¹®Á¦Á¡µéÀÌ ÀÖ´ÂÁö¸¦ ¾Ë¾Æº¸°í »õ·Î¿î ±â¼úÀÎ nio ¿¡¼ ¾î¶»°Ô ±âÁ¸ÀÇ ¹®Á¦Á¡µéÀ» ±Øº¹ÇÏ´ÂÁö °£´ÜÇÑ Ã¤ÆÃ ¼¹ö¸¦ ¸¸µé¾îº¸¸é¼ »ìÆìº¼ °ÍÀÌ´Ù. ÀÚ, ±×·³ »õ·Î¿î nio ÀÇ ¼¼°è·Î ¶°³ªº¸ÀÚ.
ÀÚ¹Ù´Â ±× Å»ý ¸ñÀûÀÌ °¡ÀüÁ¦Ç°°ú °°Àº °÷¿¡ µé¾î°¡´Â ÀÓº£µðµå ½Ã½ºÅÛÀ̾ú´Ù. ¾ÕÀ¸·Î´Â ÀÚ¹ÙÀÇ Å»ý ¸ñÀûÀÌ Á¡Â÷ µÇ»ì¾Æ³ª¼ °¢ °¡Á¤ÀÇ PC°¡ ¼¹öȵǰí, ±× PC¸¦ Áß½ÉÀ¸·Î ÇÑ °¡Á¤ÀÌ ³×Æ®¿öÅ©ÈµÇ¾î ¿©Å¸ °¡ÀüÁ¦Ç°µéÀ» Á¦¾îÇÏ°Ô µÉ °ÍÀÌ´Ù. Áï, ÈçÈ÷ ¸»Çϴ Ȩ ³×Æ®¿öÅ·ÀÌ ÀϹÝȵǴ °ÍÀÌ´Ù. ÀÌ È¨ ³×Æ®¿öÅ·¿¡¼ °¡Àå ÇÙ½ÉÀûÀÎ ¿ªÇÒÀ» ÇÏ´Â °ÍÀº ºÐ¸í °¢ °¡Á¤ÀÇ °³ÀÎ PC´Ù. ¿ì¸®´Â ÀÌ È¨ ³×Æ®¿öÅ©¸¦ ÅëÇØ ÀÎÅͳÝ, PDA, ÇÚµåÆù µîÀ¸·Î Áý¾ÈÀÇ °¡ÀüÁ¦Ç°µéÀ» Áý ¹Û¿¡¼µµ ÀÚÀ¯·Ó°Ô Á¦¾îÇÒ ¼ö ÀÖ°Ô µÈ´Ù. Áý¾È ¶Ç´Â Áý¹Û¿¡¼ ƯÁ¤ µð¹ÙÀ̽º·Î ³×Æ®¿öÅ©¿¡ Á¢¼ÓÇØ¼ ÀÌ¹Ì ³×Æ®¿öÅ©¿¡ Á¢¼ÓµÈ °¡ÀüÁ¦Ç°À» °Ë»öÇϰí Á¦¾îÇÒ ¼ö ÀÖ´Â °ÍÀÌ´Ù. ¹°·Ð ¾Õ¿¡¼ ¸»ÇÑ °ÍÀº RMI¸¦ ±â¹ÝÀ¸·Î Çϰí ÀÖ´Â Áö´Ï(Jini)¶ó´Â ÀÚ¹Ù±â¼ú·Î ±¸ÇöµÇ°ÚÁö¸¸, ½ã¸¶ÀÌÅ©·Î½Ã½ºÅÛÁî¿¡ ¶óÀ̼±½º¸¦ ÁöºÒÇØ¾ßÇÑ´Ù´Â Á¡ ¶§¹®¿¡ ´Ù¸¥ ÇüÅÂÀÇ ´Ü¼øÇÑ È¨ ³×Æ®¿öÅ©¸¦ Áö¿øÇÏ´Â °£´ÜÇÑ ÇüÅÂÀÇ ¿ÀÇ ÇÁ·¹ÀÓ¿öÅ©°¡ ³ª¿Ã ¼öµµ ÀÖÀ» °Í °°´Ù. ²À °¡ÀüÁ¦Ç°À» Á¦¾îÇÏ´Â °ÍÀÌ ¾Æ´Ï´õ¶óµµ °¡Á¤ÀÇ È¨ ¼¹ö¸¦ ÀÌ¿ëÇØ¼ µµ½Ã°¡½º »ç¿ë·®, Àü±â »ç¿ë·® µîÀ» ¿ø°ÝÁöÀÇ È¸»ç ¼¹ö¿¡¼ Á¶È¸Çϰųª ȤÀº ÀÚµ¿À¸·Î ¼¹ö¿¡ º¸³»¼ ¿ä±ÝÀ» °è»êÇϵµ·Ï ÀÚµ¿ÈÇÏ´Â µîÀÇ ´Ù¾çÇÑ ºÎºÐÀ¸·Î ¸¹Àº ÀÀ¿ë ¼ºñ½ºµéÀÇ Á¦°øÀÌ °¡´ÉÇÒ °ÍÀÌ´Ù. ¾ÕÀ¸·Î´Â Áö±ÝÀÇ Ã¤ÆÃÀ̳ª °ÔÀÓ ¼¹ö¿¡ ÇÑÁ¤µÇ¾î »ç¿ëµÇ´Â ³×Æ®¿öÅ© ÇÁ·Î±×·¥ ÂÊÀÇ °ü½É°ú ¼ö¿ä°¡ Á» ´õ ³ô¾ÆÁú °ÍÀÌ´Ù. ±×·¯³ª ±âÁ¸ÀÇ io¿Í ¼ÒÄÏÀº ÀÌ·± ¼¹ö¸¦ ¸¸µé ¶§ ¸¹Àº ¹®Á¦Á¡À» °®°í ÀÖ´Ù. ¹Ù·Î io¿Í °ü·ÃµÈ ÀÛ¾÷ÀÌ C/C++¿¡ ºñÇØ »ó´ëÀûÀ¸·Î ³Ê¹« ´À·È°í ºñµ¿±â½Ä Åë½ÅÀÌ Áö¿øµÇÁö ¾Ê¾Ò´Ù´Â Á¡ÀÌ´Ù. nio´Â ÀÌ·± ±âÁ¸ ioÀÇ ¼º´É ¹®Á¦ ¶§¹®¿¡ ÀÌ¹Ì C/C++ ¿¡¼± ÀϹÝÀûÀ¸·Î »ç¿ëµÇ´Â ºñµ¿±â½Ä Åë½ÅÀ» Áö¿øÇϱâ À§ÇØ »õ·Ó°Ô Ãß°¡µÈ ÆÐŰÁö´Ù. ±×·³ ±âÁ¸ io¿¡ ´ÜÁ¡ÀÌ ¾î¶² °ÍÀÎÁö¸¦ »ìÆìº¸°í nio¿¡¼± ¾î¶»°Ô ±× ¹®Á¦¸¦ ÇØ°áÇÏ´ÂÁö »ìÆìº¸ÀÚ.
ºó¹øÇÑ ºí·¯Å· ¹ß»ý°ú ¾²·¹µå °úºÎÇÏ
¿ì¼± ÀÚ¹Ù¿¡¼ ±âÁ¸ io¿Í ¼ÒÄÏÀ» ÀÌ¿ëÇØ ¸¸µç ¼¹ö¸¦ ºí·¯Å·(Blocking) ¼¹ö¶ó°í ÇÑ´Ù. ±× ÀÌÀ¯´Â °÷°÷¿¡ ³Ê¹« ¸¹Àº ºí·¯Å·ÀÌ Á¸ÀçÇ߱⠶§¹®Àε¥ ¿©±â¼ ºí·¯Å·À̶õ ¾Õ¼± ¿äûÀÇ Ã³¸®°¡ ´Ù ó¸®µÉ ¶§±îÁö µÚÀÇ ¿äûÀÌ ±â´Ù·Á¾ß ÇÏ´Â °ÍÀ» ¸»ÇÑ´Ù. ±âÁ¸ÀÇ ÀϹÝÀûÀÎ ÇüÅÂÀÇ ¼¹ö¿¡¼ ¾î´À ºÎºÐÀÌ ºí·¯Å·ÀÌ µÇ´ÂÁö <±×¸² 1>¿¡¼ »ìÆìº¸ÀÚ.

<±×¸² 1> ±âÁ¸ ¼¹ö¿¡¼ ºí·¯Å·ÀÌ µÇ´Â ºÎºÐ
<±×¸² 1>¿¡¼ »¡°£»ö ±Û¾¾·Î Ç¥½ÃµÈ ºÎºÐÀÌ ºí·¯Å·ÀÌ µÇ´Â ºÎºÐÀÌ´Ù. ºí·¯Å·Àº ÀÚ¹ÙÀÇ synchronize Ű¿öµå¿Í °°´Ù°í »ý°¢ÇÏ¸é ½±°Ô ÀÌÇØµÉ °ÍÀÌ´Ù. Áï, ¾î¶² ÀÛ¾÷À» Çϱâ À§ÇØ ¸ÕÀú Á¢±ÙÇÑ ¿äûÀÌ ´Ù ³¡³ª±â Àü¿¡´Â µÚÀ̾î Á¢±ÙÇÑ ¿äûµéÀº ¸ÕÀú µé¾î¿Â ¿äûÀÌ ´Ù ³¡³ª±â¸¦ ±â´Ù·Á¾ß ÇÏ´Â °ÍÀÌ´Ù. ¸¸¾à ¾Õ¼± ¿äûÀÌ ¾î¶² ¹®Á¦Á¡¿¡ ÀÇÇØ ¿ÏÀüÈ÷ 󸮵ÇÁö ¾Ê°í ºí·°µÈ »óÅ·ΠÀÖ°Ô µÈ´Ù¸é µÚÀÌÀº ¿äûµéÀº ¿µ¿øÈ÷ ¾Õ¼± ¿äûÀÌ ³¡³ª±â¸¸À» ±â´Ù¸± °ÍÀÌ´Ù. ÀÌ¿¡ ¹ÝÇØ Non-Blocking Àº µé¾î¿Â ¿äûÀ» ¹Ù·Î ó¸®ÇÏ´Â °ÍÀÌ´Ù. Áï, ¾Õ¼± ¿äûÀÌ ´Ù ³¡³ª±â¸¦ ±â´Ù¸®Áö ¾Ê¾Æµµ µÈ´Ù. ¸ÕÀú ´ÙÀ½°ú °°ÀÌ ¼¹ö¿¡ Á¢¼ÓÇØ¼ accept()¸¦ È£ÃâÇÏ´Â ºÎºÐ¿¡¼ ºí·¯Å·ÀÌ ¹ß»ýÇÑ´Ù.
ServerSocket ss = new ServerSocket(4567);
while(true) {
Socket s = ss.accept();
...
// µ¿½Ã¿¡ ¿©·¯ Ŭ¶óÀÌ¾ðÆ®µéÀÇ ¿äûÀ» ¼öÇàÇϱâ À§ÇØ º°µµÀÇ ¾²·¹µå¸¦ ¸¸µé¾î¼ ó¸®ÇÔ.
Service service = new Service(s);
service.start();
...
}
¾Õ¿¡¼ accept()´Â ¾î¶² Ŭ¶óÀÌ¾ðÆ®°¡ Á¢¼ÓÇÒ ¶§±îÁö ºí·¯Å·ÀÌ µÈ´Ù. ¸¸¾à ¾î¶² Ŭ¶óÀÌ¾ðÆ®°¡ accept()¸¦ È£ÃâÇÏ¸é µÚÀ̾î ÀÌ ¼¹ö ¼ÒÄÏÀ¸·Î Á¢¼ÓÇÑ Å¬¶óÀÌ¾ðÆ®´Â ¸ÕÀú Á¢¼ÓÇÑ Å¬¶óÀ̾ðÆ®ÀÇ ¿äûÀÌ ´Ù 󸮵DZ⸦ ±â´Ù·Á¾ßÇÑ´Ù(¾ÕÀÇ Äڵ忡¼´Â while¹® ¾ÈÀÇ accept() ÀÌÇÏÀÇ ºÎºÐÀÌ ´Ù ó¸®µÉ ¶§±îÁö ±â´Ù¸²) ¶ÇÇÑ µ¿½Ã¿¡ ¿©·¯ Ŭ¶óÀÌ¾ðÆ®µéÀÇ ¿äûÀ» ó¸®Çϱâ À§Çؼ º°µµÀÇ ¾²·¹µå·Î Service Ŭ·¡½º¸¦ ¸¸µé¾î¼ ó¸®Çϴµ¥, À̰ÍÀº »ç¿ëÀÚ°¡ ´Ã¾î³¯ °æ¿ì Ŭ¶óÀÌ¾ðÆ® ÇÑ ¸í¸¶´Ù ÇϳªÀÇ ¾²·¹µå¸¦ ÇÒ´çÇØÁÖ´Â ÇüŰ¡ µÇ¹Ç·Î ¾²·¹µå °úºÎÇϸ¦ °¡Á®¿À°Ô µÈ´Ù.
¡ß Thread issue : ¾²·¹µå´Â ±× ÀÚüÀûÀ¸·Îµµ »ý¼ºÇϴµ¥ ½Ã°£ÀÌ °É¸®´Â ´À¸° ÀÛ¾÷À̱⵵ ÇÏ°í °¢°¢ÀÇ ¾²·¹µåµéÀÌ ÀڽŸ¸ÀÇ °íÀ¯ÇÑ ½ºÅÃ(stack) ¿µ¿ª°ú CPU¸¦ Á¡À¯Çؼ »ç¿ëÇϱ⠶§¹®¿¡ ¾ÕÀÇ ÄÚµå ºÎºÐó·³ ¸¹Àº ¾²·¹µå¸¦ »ý¼ºÇØ¾ß ÇÏ´Â ¼¹ö´Â ¸Þ¸ð¸®¿Í CPU¸¦ È¿À²ÀûÀ¸·Î »ç¿ëÇÏÁö ¸øÇÑ´Ù. ¶ÇÇÑ Å¬¶óÀÌ¾ðÆ®µéÀÇ µ¿½Ã 󸮸¦ À§ÇØ »ý¼ºµÈ Service ¾²·¹µåµéÀÌ ´ëºÎºÐÀÇ Ã³¸® ½Ã°£À» ¿äû/ÀÀ´äÀÇ ºí·¯Å· ºÎºÐ¿¡¼ ¼ÒºñÇÑ´Ù´Â °Íµµ ¹®Á¦Á¡ÀÌ´Ù. ±×¸®°í °áÁ¤ÀûÀ¸·Î ÇϳªÀÇ JVM Àº ¸î ¹é°³±îÁöÀÇ ¾²·¹µå¸¦ »ý¼ºÇؼ ¿î¿µÇÒ ¼ö ÀÖÁö¸¸ ¼ö õ°³ÀÇ ¾²·¹µå¸¦ »ý¼ºÇÒ ¼ö´Â ¾ø´Ù. ¶ÇÇÑ ½Ã½ºÅÛ¿¡ µû¶ó ±× ½ÃÁ¡Àº ´Ù¸£Áö¸¸ ´ë°³ÀÇ °æ¿ì ƯÁ¤ °³¼ö ÀÌ»óÀÇ ¾²·¹µå¸¦ »ý¼ºÇÏ¸é ±Þ°ÝÇÑ ¼º´É ÀúÇϸ¦ º¸À̱⵵ Çϱ⠶§¹®ÀÌ´Ù.
´ÙÀ½ ÄÚµå´Â Service Ŭ·¡½º¿¡¼ Ŭ¶óÀÌ¾ðÆ® ¿äûÀ» Àаí ÀÀ´äÀ» º¸³»´Â ºÎºÐ¿¡¼ ºí·¯Å·ÀÌ ¹ß»ýÇÏ´Â °ÍÀ» ³ªÅ¸³½ °ÍÀÌ´Ù.
public class Service implements Thread {
private Socket s;
private DataInputStream in;
private DataOutputStream out;
public Service(Socket s) {
this.s = s;
// ÀÌ ºÎºÐ¿¡¼ ¿äûÀ» Àаí ÀÀ´äÀ» º¸³¾ ¶§ ºí·¯Å· µÊ.
in = new DataInputStream(new BufferedInputStream(s.getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(s.getOutputStream()));
}
...
}
¿äû, ÀÀ´ä ºÎºÐ¿¡¼ ºí·¯Å·ÀÌ µÇ¹Ç·Î ¾ÆÁÖ ºó¹øÇÏ°Ô ºí·¯Å·ÀÌ ¹ß»ýÇÏ°Ô µÈ´Ù. ±×·¡¼ ¾ÆÁÖ ºñÈ¿À²ÀûÀÎ(´À¸°) ¼¹öÀÇ ±¸¼ºÀÌ µÇ´Â °ÍÀ» ¾Ë ¼ö ÀÖÀ» °ÍÀÌ´Ù. ¾ÕÀÇ Äڵ忡¼ Stream¿¡¼ StreamÀ¸·Î µ¥ÀÌÅ͸¦ Àü´ÞÇÏ´Â °úÁ¤¿¡¼ µ¥ÀÌÅÍ º¹»ç°¡ ÀÌ·ïÁö°í, ÀÌ º¹»ç°¡ ´Ù ³¡³¯ ¶§±îÁö ºí·¯Å·ÀÌ µÈ´Ù. ¶ÇÇÑ È¿À²À» ³ôÀ̱â À§ÇØ s.getInputStream()À¸·Î Àоî¿Â µ¥ÀÌÅ͸¦ BufferedInputStream ¹öÆÛ¿¡ ³Ö°í À̰ÍÀ» ´Ù½Ã DataInputStreamÀ¸·Î Àü´ÞÇßÁö¸¸, Stream¿¡¼ StreamÀ¸·Î µ¥ÀÌÅ͸¦ º¹»çÇØ¼ Àü´ÞÇϹǷΠ³Ê¹« ¸¹Àº °¡ºñÁö(garbage, ¼Ò¸ê ´ë»ó µ¥ÀÌÅÍ)°¡ »ý¼ºµÈ´Ù. Stream¿¡¼ Àü´ÞµÇ´Â µ¥ÀÌÅÍ´Â ´ëºÎºÐ ƯÁ¤ ¸ñÀûÀ¸·Î Çѹø »ç¿ëµÇ°í °ð¹Ù·Î °¡ºñÁö Ä÷º¼Ç(Garbage Collection) ´ë»óÀÌ µÈ´Ù. ¿¹¸¦ µé¾î äÆÃ ¼¹ö¿¡¼ Ŭ¶óÀÌ¾ðÆ®°¡ º¸³½ ´ëÈ ¸Þ½ÃÁö(String)´Â ¼¹ö¿¡¼ ´ëÈ¹æ ¾ÈÀÇ Å¬¶óÀÌ¾ðÆ®µé¿¡°Ô ºê·Îµåij½ºÆ®ÇÑ ÈÄ ´õ ÀÌ»ó ¾µ¸ð¾ø´Â µ¥ÀÌÅͰ¡ µÇ±â ¶§¹®¿¡ °ð¹Ù·Î °¡ºñÁö Ä÷º¼Ç ´ë»óÀÌ µÇ´Â °ÍÀÌ´Ù. µû¶ó¼ StreamÀ¸·Î µ¥ÀÌÅ͸¦ º¹»çÇØ¼ Àü´ÞÇÑ´Ù´Â °ÍÀº ¶È°°Àº µ¥ÀÌÅÍ¿¡ ´ëÇØ ÇÑ °³ÀÇ °¡ºñÁö°¡ ´õ »ý¼ºµÇ´Â °ÍÀÌ´Ù. °¡ºñÁö°¡ ¸¹ÀÌ »ý¼ºµÈ´Ù´Â °ÍÀº °¡ºñÁö Ä÷ºÅͰ¡ ±×¸¸Å ÀÚÁÖ È£ÃâµÈ´Ù´Â °ÍÀ» ÀǹÌÇϰí, À̰ÍÀº ÆÛÆ÷¸Õ½º¿¡ ¾Ç¿µÇâÀ» ÁÖ°Ô µÇ´Â ¿äÀÎÀÌ µÈ´Ù. °á·ÐÀûÀ¸·Î ±âÁ¸ÀÇ io¿¡¼´Â È¿À²À» À§ÇØ ´õ ¸¹Àº °¡ºñÁö »ý¼ºÀ» °¨¼öÇÏ°í ¹öÆÛ¸µÀ» ÇÏ´À³Ä ±×·¸°Ô ÇÏÁö ¾Ê´À³Ä´Â °¢°¢ÀÇ Àå´ÜÁ¡À» °®´Â ¾ç³¯ÀÇ Ä®°úµµ °°¾Ò´Ù. ÇÏÁö¸¸ ´ë°³ÀÇ °æ¿ì ¹öÆÛ¸µÀ» »ç¿ëÇÑ´Ù. ±× ÀÌÀ¯´Â ¼¹ö ÇÁ·Î±×·¡¹Ö¿¡¼ ÃÖ¿ì¼±ÀûÀ¸·Î °í·ÁÇÒ »çÇ×ÀÌ ¹Ù·Î È¿À²(¼Óµµ)À̱⠶§¹®ÀÌ´Ù.
¡ß °¡ºñÁö Ä÷º¼Ç : ÇÁ·Î±×·¥Àº ÇÁ·Î±×·¥À» ÁøÇàÇÏ¸é¼ µ¥ÀÌÅ͵éÀ» ÀúÀåÇÏ´Â °ÍÀÌ ÇÊ¿äÇÏ´Ù. µ¥ÀÌÅ͵éÀº ¸ðµÎ ¸Þ¸ð¸®¿¡ ÀúÀåÀÌ µÇ´Âµ¥, ÀúÀåÇÒ µ¥ÀÌÅͰ¡ ÀÖÀ¸¸é ¸Þ¸ð¸®ÀÇ ÀÏÁ¤ °ø°£À» ÇÒ´ç¹Þ¾Æ¼ »ç¿ëÇÏ´Â °ÍÀÌ´Ù. ±×·±µ¥ ´õ ÀÌ»ó »ç¿ëµÇÁö ¾Ê´Â µ¥ÀÌÅÍ¿¡°Ô ¸Þ¸ð¸®¸¦ °è¼Ó ÇÒ´çÇØ ÁÖ´Â °ÍÀº ¸Þ¸ð¸®¸¦ ³¶ºñÇÏ´Â °ÍÀ̹ǷÎ, ±× µ¥ÀÌÅͰ¡ »ç¿ëÇÏ´ø ¸Þ¸ð¸®¸¦ ȸ¼öÇÏ´Â °ÍÀÌ ÇÊ¿äÇÏ´Ù. ÀÌ·¸°Ô »ç¿ëµÇÁö ¾Ê´Â ¸Þ¸ð¸®¿¡ ´ëÇÑ È¸¼ö¸¦ °¡ºñÁö Ä÷º¼ÇÀ̶ó°í Çϰí À̰ÍÀ» ¼öÇàÇÏ´Â °ÍÀ» °¡ºñÁö Ä÷ºÅͶó°í ÇÑ´Ù. ±×·¯³ª ¾î¶² µ¥ÀÌÅͰ¡ »ç¿ëµÇÁö ¾Ê´Â´Ù°í ÇØ¼ °ð¹Ù·Î °¡ºñÁö Ä÷ºÅͰ¡ ½ÇÇàµÇ¾î ¸Þ¸ð¸®¸¦ ȸ¼öÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. ¿ì¼±Àº ¾µ¸ð¾ø´Â µ¥ÀÌÅͰ¡ °¡ºñÁö Ä÷º¼ÇÀÇ ´ë»óÀ¸·Î ÁöÁ¤µÇ°í ÇÁ·Î±×·¥ÀÌ ÁøÇàµÇ±â À§ÇØ ¸Þ¸ð¸®°¡ ´õ ÇÊ¿äÇÏ°Ô µÇ¸é, ±×¶§ °¡¼ ¸Þ¸ð¸®¸¦ ȸ¼öÇÏ´Â °ÍÀÌ´Ù.
¡ß °¡ºñÁö Ä÷ºÅÍ À̽´(Garbage Collector issue) : ÀÚ¹Ù¿¡¼´Â ¸Þ¸ð¸®¸¦ JVMÀÌ ¾Ë¾Æ¼ ¼ö°ÅÇÑ´Ù. ÇÏÁö¸¸ ±×·¸°Ô ¸Þ¸ð¸®¸¦ ¼ö°ÅÇϱâ À§Çؼ °¡ºñÁö Ä÷ºÅ͸¦ ÀÌ¿ëÇϴµ¥ À̰ÍÀº »ó´çÈ÷ ¼Óµµ°¡ ´À¸° ÀÛ¾÷ÀÌ´Ù. ±×·±µ¥ ¾ÕÀÇ ÄÚµåó·³ Stream°£ ºó¹øÇÏ°Ô µ¥ÀÌÅ͸¦ º¹»çÇÏ°í »ç¿ë ÈÄ ¹Ù·Î ¼Ò¸êÇÏ´Â °ÍÀ¸·Î ÀÎÇØ ¾ÆÁÖ ¸¹Àº ¾çÀÇ µ¥ÀÌÅͰ¡ °¡ºñÁö Ä÷º¼ÇÀÇ ´ë»óÀÌ µÈ´Ù. À̰ÍÀº °ð °¡ºñÁö Ä÷ºÅͰ¡ ºó¹øÇÏ°Ô È£ÃâµÉ ¼ö ÀÖ´Ù´Â °ÍÀ» ÀǹÌÇϰí À̰ÍÀº °á±¹ ¼º´É ÀúÇϸ¦ °¡Á®¿À°Ô µÈ´Ù. °¡ºñÁö¸¦ ÀüÇô ¸¸µéÁö ¾Ê´Â ¼¹ö¸¦ ¸¸µå´Â °ÍÀÌ °¡Àå ÀÌ»óÀûÀ̰ÚÁö¸¸ ±×°Ç ¾îµð±îÁö³ª ÀÌ»óÀÏ »ÓÀÌ°í ¿ì¸®´Â ÃÖ´ëÇÑ °¡ºñÁö°¡ Àû°Ô ¸¸µé¾îÁöµµ·Ï ÇÏ´Â °ÍÀÌ °í¼º´É ¼¹ö¸¦ ¸¸µå´Â ÃÖ¼±ÀÇ ¹æ¹ýÀÌ´Ù. Áï, ÀÚ¹Ù ¼¹ö ÇÁ·Î±×·¡¹Ö¿¡¼ °íÈ¿À²ÀÇ ¼¹ö¸¦ ¸¸µé±â À§ÇØ °¡Àå ¼¼½ÉÇÑ ÁÖÀǸ¦ ±â¿ï¿©¾ßÇÏ´Â ºÎºÐÀÌ °¡ºñÁö °ü¸®ÀÎ °ÍÀÌ´Ù.
¾Õ¿¡¼ »ìÆìº» ¹Ù¿Í °°ÀÌ ÀÚ¹Ù¿¡¼ ±âÁ¸ÀÇ io¿Í ¼ÒÄÏÀº ³Ê¹« ¸¹Àº ºí·¯Å·ÀÌ Á¸ÀçÇϰí, ±¸Á¶ÀûÀ¸·Î ¸¹Àº °¡ºñÁö°¡ »ý¼ºµÉ ¼ö¹Û¿¡ ¾ø´Ù. À̰ÍÀº È¿À²ÀÌ ÃÖ¿ì¼±½Ã µÇ´Â ¼¹ö ÇÁ·Î±×·¥¿¡¼´Â ±×¸® ¹Ý°©Áö ¸øÇÑ Á¶°ÇÀÌ´Ù.
»õ·Î¿î ´ë¾È, ºñµ¿±â½Ä ¼¹öÀÇ µîÀå
¾Õ¼ ¼³¸íÇÑ µ¿±â½Ä ¼¹öÀÇ ¹®Á¦Á¡µéÀ» ÇØ°áÇϱâ À§ÇØ J2SDK1.4¿¡¼ nio°¡ ³ª¿Ô´Ù. nio¿¡¼´Â accept()¿Í Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû/ÀÀ´ä¿¡ ´ëÇØ ºí·¯Å·ÀÌ ¾ø´Ù. À̰ÍÀ» °¡´ÉÇÏ°Ô ÇÑ °ÍÀº ä³Î(Channel) ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇöÇÏ´Â SelectableChannelÀ̶ó´Â »õ·Î¿î Ŭ·¡½º¸¦ non-blockingÀ¸·Î ¼³Á¤ÇÔÀ¸·Î½á accept()¿¡ ´ëÇÑ ºí·¯Å·À» ÇÇÇÒ ¼ö ÀÖµµ·Ï Çß°í, Buffer¶ó´Â »õ·Î¿î Ŭ·¡½ºÀÇ µµÀÔÀ¸·Î ÀÔÃâ·Â ÀÛ¾÷¿¡¼ ºí·¯Å·À» ÇÇÇÏ°í ±âÁ¸ io¿¡¼ÀÇ Stream°£ÀÇ µ¥ÀÌÅÍ º¹»ç¿¡ ÀÇÇÑ °¡ºñÁö »ý¼ºÀ» ¿¹¹æÇÔÀ¸·Î½á È¿À²ÀûÀÎ ¹öÆÛ¸µÀÌ °¡´ÉÇØÁ³´Ù. ¶ÇÇÑ Ã¤³Î°ú ¹öÆÛ(direct buffer)´Â ³×ÀÌÆ¼ºê Á¢±ÙÀ» ÇÔÀ¸·Î½á ±âÁ¸ÀÇ µ¿±â½Ä ¼¹öº¸´Ù ÈξÀ ³ªÀº ¼º´ÉÀ» °®Ãâ ¼ö ÀÖ´Ù. ±×·³ nioÀÇ ÇÙ½É ±¸¼º¿ä¼ÒµéÀ» »ìÆìº¸ÀÚ.
ps. Á» ´õ Á¤È®ÇÏ°Ô ¸»ÇÏÀÚ¸é nio ´Â ¿Ïº®ÇÑ ºñµ¿±â½ÄÀÌ ¾Æ´Ï´Ù. ±×°Íº¸´Ù´Â ³ºí·¯Å·(non-blocking)À̶ó´Â Ç¥ÇöÀÌ ´õ ÀûÀýÇÒ °ÍÀÌ´Ù. ¿Ïº®ÇÑ ºñµ¿±â½Ä ¼ÒÄÏ Åë½ÅÀÇ Áö¿øÀº 1.5 ŸÀ̰ſ¡¼ ³ª¿Â´Ù´Â ¾ê±â°¡ ÀÖÀ¸´Ï ±â´ëÇØ º¸ÀÚ.
È¿À²ÀûÀÎ io ÀÛ¾÷À» À§ÇØ Åº»ýÇÑ Buffer
ÀÚ¹Ù¿¡¼ °í¼º´É ¼¹ö¸¦ ¸¸µé±â À§ÇØ ¹Ýµå½Ã °í·ÁÇØ¾ßÇÒ °Í Áß Çϳª°¡ ¹Ù·Î °¡ºñÁö Ä÷º¼ÇÀÌ´Ù. Áï, °¡ºñÁö¸¦ ÃÖ´ëÇÑ Àû°Ô ¸¸µé¾î¼ ÃÖ´ëÇÑ °¡ºñÁö Ä÷ºÅÍ È£ÃâÀ» ÃÖ¼ÒȽÃÄÑ¾ß ÇÑ´Ù. ±×·¯³ª ±âÁ¸ io¿¡¼´Â ³Ê¹« ¸¹Àº °¡ºñÁö°¡ »ý¼ºµÇ´Â ±¸Á¶Àû ¹®Á¦Á¡ÀÌ ÀÖ¾ú´Ù. ÀÌ·± ¹®Á¦Á¡ÀÇ ÇØ°á¹æ¾ÈÀ¸·Î nio¿¡¼´Â Buffer¶ó´Â »õ·Î¿î Ŭ·¡½º°¡ Ãß°¡µÆ´Ù. ±×·³ ÀÌÁ¦ºÎÅÍ Buffer¿¡ ´ëÇØ ÀÚ¼¼ÇÏ°Ô »ìÆìº¸°Ú´Ù.
Buffer ´Â ±× Ŭ·¡½º ŸÀÔ¿¡ µû¶ó ÇϳªÀÇ µ¥ÀÌÅÍ Å¸ÀÔ¸¸À» ÀúÀåÇÒ ¼ö ÀÖ´Â ¼±ÇüÀÇ ¼øÂ÷Àû datasetÀÌ´Ù. nio ¹öÆÛ ±ºÀÇ ÃÖ»óÀ§ abstract Ŭ·¡½ºÀÎ Buffer¸¦ Áß½ÉÀ¸·Î ¾Æ·¡ Ç¥¿Í °°Àº ´Ù¾çÇÑ Á¾·ùÀÇ Å¬·¡½ºµéÀÌ Á¸ÀçÇÑ´Ù.
<Ç¥ 1> java.nioÀÇ Buffer Ŭ·¡½ºµé
| ±¸ºÐ
| ³»¿ë
|
| java.nio.Buffer
| abstract Ŭ·¡½º. ¸ðµç BufferÀÇ super Ŭ·¡½º.
|
| java.nio.ByteBuffer
| byte ±â¹Ý ¹öÆÛ. direct¿Í nondirect µÎ °¡Áö ¹æ½ÄÀ¸·Î »ý¼ºÇÒ ¼ö ÀÖÀ½. ReadableByteChannel·ÎºÎÅÍ ÀÐÀ» ¼ö ÀÖ°í WritableByteChannel·Î ¾µ ¼ö ÀÖÀ½.
|
| java.nio.MappedByteBuffer
| byte ±â¹Ý ¹öÆÛ. Ç×»ó direct ·Î »ý¼ºµÊ. ÆÄÀÏÀÇ ¸Þ¸ð¸®¸Ê ¿µ¿ªÀ» ³»¿ëÀ¸·Î ÇÏ´Â ¹öÆÛ. ByteBufferÀÇ ¼ºê Ŭ·¡½ºÀÓ.
|
| java.nio.CharBuffer
| char ±â¹Ý ¹öÆÛ. ä³Î¿¡ ¾µ ¼ö ¾øÀ½.
|
| java.nio.DoubleBuffer
| double ±â¹Ý ¹öÆÛ. ä³Î¿¡ ¾µ ¼ö ¾øÀ½.
|
| java.nio.FloatBuffer
| float ±â¹Ý ¹öÆÛ. direct¿Í nondirect µÎ °¡Áö ¹æ½ÄÀ¸·Î »ý¼ºÇÒ ¼ö ÀÖÀ½.
|
| java.nio.IntBuffer
| int ±â¹Ý ¹öÆÛ. direct¿Í nondirect µÎ °¡Áö ¹æ½ÄÀ¸·Î »ý¼ºÇÒ ¼ö ÀÖÀ½.
|
| java.nio.LongBuffer
| long ±â¹Ý ¹öÆÛ. direct¿Í nondirect µÎ °¡Áö ¹æ½ÄÀ¸·Î »ý¼ºÇÒ ¼ö ÀÖÀ½.
|
| java.nio.ShortBuffer
| short ±â¹Ý ¹öÆÛ. direct¿Í nondirect µÎ °¡Áö ¹æ½ÄÀ¸·Î »ý¼ºÇÒ ¼ö ÀÖÀ½.
|
Buffer´Â ¼¼ °¡Áö ¿ä¼Ò·Î ±¸¼ºµÇ´Âµ¥ ¹Ù·Î capacity, position, limitÀÌ´Ù.
¡ß capacity : ¹öÆÛ¸¦ ¸¸µé ¶§ »ç¿ëÇÏ´Â ¹öÆÛÀÇ ¿ë·®(Å©±â)ÀÌ´Ù. Ãʱ⿡ ±âÀÔµÈ °ªÀÌ °íÁ¤µÇ¹Ç·Î ÀûÀýÇÑ ¿ë·®À¸·Î ¹öÆÛ¸¦ »ý¼ºÇØ¾ß ÇÑ´Ù.
¡ß position : ¹öÆÛÀÇ ÇöÀç À§Ä¡°¡ ¾îµðÀÎÁö¸¦ °¡¸®Å°´Â À妽ºÀÌ´Ù. positionÀÌ °¡Áú ¼ö ÀÖ´Â °ªÀº limit ÀÌÇÏÀÇ °ªÀÌ´Ù.
¡ß limit  : ÇØ´ç ¹öÆÛ¿¡ ´õ ÀÌ»ó Àаųª ¾µ ¼ö ¾ø´Â ´ÙÀ½ ¿ä¼ÒÀÇ À妽ºÀÌ´Ù. ±×·¯¹Ç·Î limit¿Í positionÀÇ Â÷´Â ¹öÆÛÀÇ ¡®³²Àº °ª¡¯À» ÀǹÌÇÑ´Ù.
abstract Ŭ·¡½ºÀÎ Buffer¸¦ »ó¼ÓÇÏ´Â ¼ºêŬ·¡½ºµéÀº °øÅëÀûÀ¸·Î allocate(int capacity) ¶Ç´Â allocateDirect(int capacity)¸¦ ÅëÇØ¼ ¹öÆÛ¸¦ »ý¼ºÇÑ´Ù. ¶ÇÇÑ ÀÌ¹Ì Á¸ÀçÇÏ´Â ¹è¿À» wrapÇÏ´Â ¹æ½Ä(¿¹ : ByteBuffer.wrap(byte[] buffer))À¸·Î ¹öÆÛ¸¦ »ý¼ºÇÒ ¼öµµ ÀÖ´Ù. Ưº°ÇÑ °æ¿ì·Î´Â MappedByteBufferÀÇ °æ¿ì FileChannel.map(int mode, long position, int size)·Î ¹öÆÛ¸¦ »ý¼ºÇÒ ¼ö ÀÖ´Ù.
allocateDirect(int capacity)·Î »ý¼ºÇÏ´Â direct buffer´Â ¸Þ¸ð¸® ºí·°¿¡ ¿¬¼ÓÀûÀ¸·Î ÇÒ´çµÇ°í ¹öÆÛÀÇ µ¥ÀÌÅ͸¦ Àаųª ¾²±â À§ÇØ ³×ÀÌÆ¼ºê Á¢±Ù ¸Þ½îµåµéÀ» »ç¿ëÇÏ°Ô µÈ´Ù. direct buffer´Â nondirect buffer¿¡ ºñÇØ ¹öÆÛ¸¦ »ý¼º/ÇØÁ¦ Çϴµ¥ ´õ ¸¹Àº ºñ¿ëÀÌ µéÁö¸¸ ¼Óµµ°¡ ´õ ºü¸¥ Ư¡ÀÌ ÀÖ´Ù. µû¶ó¼ direct buffer´Â Å« ¿ë·®ÀÇ ¹öÆÛ¸¦ ¿À·£ ½Ã°£µ¿¾È À¯ÁöÇØ¾ß ÇÏ°í ºü¸¥ 󸮸¦ ¿øÇÒ °æ¿ì¿¡ »ý¼ºÇÏ´Â °ÍÀÌ ¹Ù¶÷Á÷ÇÏ´Ù. ¹Ù·Î ¿ì¸®°¡ ¸¸µé äÆÃ ¼¹ö¿Í °°Àº ¼¹ö ÇÁ·Î±×·¥¿¡¼ ByteBufferPool(12¿ùÈ£¿¡¼ ¼Ò°³µÊ)À» ¸¸µé¾î¼ »ç¿ëÇÏ´Â °ÍÀÌ ÀûÀýÇÑ ¿¹°¡ µÉ °ÍÀÌ´Ù. allocate(int capacity)·Î »ý¼ºÇÏ´Â nondirect buffer´Â ÀÚ¹ÙÀÇ ¹è¿ Á¢±ÙÀÚµé(get/put ¸Þ¼Òµåµé)À» ÅëÇØ ¹öÆÛÀÇ µ¥ÀÌÅÍ¿¡ Á¢±ÙÇÑ´Ù.
ÀÌ µÎ °¡Áö ŸÀÔÀÇ ¹öÆÛ Â÷ÀÌ´Â ´ÜÁö ¾Õ¼ ¼³¸íÇÑ´ë·Î ¸Þ¸ð¸®¿¡ ÇÒ´çµÇ´Â °Í°ú ÀÐ°í ¾²±â À§ÇØ ³×ÀÌÆ¼ºê Á¢±ÙÀ» Çϴ°¡ ¾Æ´Ñ°¡ Á¤µµÀÌ´Ù. ±×·³ °¡Àå ÈçÈ÷ ¾²ÀÏ ByteBuffer¸¦ ¿¹Á¦·Î ÇØ¼ »ç¿ë¹ýÀ» ¾Ë¾Æº¸ÀÚ.
ByteBuffer buffer = ByteBuffer.allocateDirect(10);
ÀÌ¿Í °°ÀÌ direct ¹öÆÛ¸¦ »ý¼ºÇϸé <±×¸² 2>¿Í °°ÀÌ position=0, capacity=10, limit=10ÀÎ »õ·Î¿î ¹öÆÛ°¡ »ý¼ºµÈ´Ù. »õ·Î¿î ¹öÆÛ¸¦ »ý¼ºÇϸé capacity¿Í limit°¡ °°°Ô µÈ´Ù.

<±×¸² 2> capacity°¡ 10ÀÎ Direct ¹öÆÛ »ý¼º
¹öÆÛÀÇ positionÀº Àаųª ¾²±â À§ÇÑ ´ÙÀ½ ¿ä¼ÒÀÇ À妽ºÀÌ´Ù. ¾ÕÀÇ °æ¿ì¿£ ¹öÆÛ¸¦ »õ·Î »ý¼ºÇßÀ¸¹Ç·Î positionÀÌ 0¹øÂ° À§Ä¡¸¦ °¡¸®Å°°Ô µÈ´Ù. ¶ÇÇÑ ¹öÆÛ¿¡ µ¥ÀÌÅ͸¦ Ãß°¡Çϸé positionÀº limit ÂÊÀ¸·Î À̵¿ÇÏ°Ô µÈ´Ù. ±×·³ ¹öÆÛ¿¡ µ¥ÀÌÅ͸¦ Ãß°¡½ÃÄÑ º¸ÀÚ.
buffer.put( (byte)0xaa );
buffer.putShort( (short)0xbbcc );
buffer.put( (byte)0xdd );
ÀÌ Ã³·³ ¹öÆÛ¿¡ µ¥ÀÌÅ͸¦ Ãß°¡Çϸé 1byte¾¿ Â÷·Ê´ë·Î ÀúÀåµÇ±â ¶§¹®¿¡ <±×¸² 3>°ú °°ÀÌ 4byteÀÇ °ø°£¿¡ ¼ø¼´ë·Î ÀúÀåµÇ°í position=4°¡ µÈ´Ù. putShort()·Î ÀúÀåÇÑ ºÎºÐÀ» ÁÖÀÇÇØ¼ ºÁ¾ß ÇÑ´Ù. short´Â 16bitÀ̱⠶§¹®¿¡ 1byte ¾¿ ¼ø¼´ë·Î 2byte°¡ ÀúÀåµÈ´Ù.

<±×¸² 3> ¹öÆÛ¿¡ put() À¸·Î µ¥ÀÌÅ͸¦ Ãß°¡
¹öÆÛ¿¡ µ¥ÀÌÅ͸¦ ³ÖÀ» ¶§ ÁÖÀÇÇÒ °ÍÀº ¹öÆÛÀÇ limit¸¦ ³Ñ¾î¼ ¹öÆÛ¿¡ µ¥ÀÌÅ͸¦ ¾²·Á¸é BufferOverflowExceptionÀÌ ¹ß»ýÇÑ´Ù´Â °ÍÀÌ´Ù. ºñ½ÁÇÏ°Ô ¹öÆÛÀÇ limit¸¦ ³Ñ¾î¼ µ¥ÀÌÅ͸¦ ÀÐÀ¸·Á¸é BufferUnderflowExceptionÀÌ ¹ß»ýÇÑ´Ù. ÀÌ·± °æ¿ì ¹öÆÛ¿¡ ä¿öÁø µ¥ÀÌÅ͸¦ ÀÐÀ¸¸é µÇ¸ç, ä³Î¿¡ ¾²±â À§Çؼ´Â ¹Ýµå½Ã ¹öÆÛ¸¦ Çø³(flip)½ÃÄÑ¾ß ÇÑ´Ù.
buffer.flip();
¹öÆÛ¸¦ Çø³½Ã۸é <±×¸² 4>¿¡¼Ã³·³ ¹öÆÛÀÇ positionÀ» ¸Ç ¾ÕÀ¸·Î(0À¸·Î) À̵¿Çϰí Çø³Çϱâ ÀüÀÇ positionÀÌ limit·Î ¼³Á¤µÈ´Ù. ±×·¯³ª ¾Õ¼ ¼³¸íÇßµíÀÌ capacity´Â º¯ÇÏÁö ¾Ê°í °íÁ¤µÇ¾î ÀÖ´Ù. ¹öÆÛ¸¦ Çø³½ÃŰ°í ³ª¸é ¹öÆÛ¸¦ ÀÐÀ» ¼ö ÀÖ´Â »óŰ¡ µÈ´Ù.

<±×¸² 4> ¹öÆÛ¸¦ flip()½ÃŲ °æ¿ì
<±×¸² 4>¿¡¼ ¹öÆÛ¸¦ Çø³½ÃŰ°í ³ª¼ position°ú limit°¡ º¯ÇÑ °ÍÀ» º¼ ¼ö ÀÖ´Ù(³ª¸ÓÁö ¹öÆÛÀÇ »ç¿ëµµ À̰Ͱú Å©°Ô ´Ù¸£Áö ¾ÊÀ¸´Ï API ¹®¼¸¦ ÅëÇØ »ç¿ë¹ýÀ» ÀÍÈ÷±â ¹Ù¶õ´Ù). CharBuffer¿Í java.nio.charset ÆÐŰÁöÀÇ Charset Ŭ·¡½º·Î ÀÎÄÚµùÇÏ´Â °ÍÀº Áö¸é °ü°è»ó ¼³¸íÇÏÁö ¾Ê¾ÒÁö¸¸ ²À ½Å°æ½á ºÁµÎ±â ¹Ù¶õ´Ù.
ºñµ¿±â½Ä ¼ÒÄÏ Åë½ÅÀ» À§ÇÑ Ã¤³Î
ä³ÎÀº Çϵå¿þ¾î µð¹ÙÀ̽º, ÆÄÀÏ, ³×Æ®¿öÅ© ¼ÒÄÏ µîÀÌ »óÈ£°£¿¡ Àб⳪ ¾²±â µîÀÇ ÀÔÃâ·Â ÀÛ¾÷À» ÇÑ °³ ÀÌ»ó ¼öÇàÇÒ ¼ö ÀÖ´Â Ãß»óÈµÈ °èÃþÀÌ´Ù. ÃÖ»óÀ§ÀÇ java.nio.channel.ChannelÀº ´ÜÁö Open ¶Ç´Â Close »óŸ¸À» ³ªÅ¸³»´Âµ¥ ¸¸¾à ä³ÎÀÌ closeµÈ »óÅ¿¡¼ ÀÔÃâ·Â ÀÛ¾÷À» ½ÇÇàÇÏ·Á¸é ClosedChannelExceptionÀÌ ¹ß»ýµÈ´Ù. ±×¸®°í ä³ÎÀº ¸ÖƼ ¾²·¹µå Á¢±Ù¿¡ ´ëÇØ ¾ÈÀüÇÏ´Ù. ä³ÎÀÇ ÀåÁ¡Àº ³×ÀÌÆ¼ºê Á¢±ÙÀ» ÅëÇØ ¼Óµµ°¡ ºü¸£´Ù´Â °Í°ú ¾î¶² ¾²·¹µå°¡ ƯÁ¤ ä³Î¿¡ ´ëÇÑ ÀÛ¾÷ Áß ºí·°µÆÀ» ¶§ ´Ù¸¥ ¾²·¹µå°¡ ±× ä³ÎÀ» Á¾·á½Ãų ¼ö ÀÖ´Ù´Â °ÍÀÌ´Ù. ´Ù¸¥ ¾²·¹µå°¡ ä³ÎÀ» Á¾·á½ÃŰ¸é ºí·ÏµÈ ¾²·¹µå´Â ä³ÎÀÌ Á¾·áÇÒ ¶§ °ü°èµÈ Exception°ú ÇÔ²² ±ú¾î³ª°Ô µÈ´Ù. Áï, ¾î¶² ÀÛ¾÷ Áß¿¡ ºí·°µÆÀ» ¶§ È¿°úÀûÀÎ ´ëó°¡ °¡´ÉÇÑ °ÍÀÌ´Ù. <±×¸² 5>´Â ä³ÎÀÇ °èÃþµµÀÌ´Ù.

<±×¸² 5> ä³Î °èÃþµµ
<±×¸² 5>¿¡¼ º¼ ¼ö ÀÖµíÀÌ ScatteringByteChannelÀº µ¥ÀÌÅ͸¦ Àдµ¥ »ç¿ëµÇ°í GatheringByteChannelÀº writeÇϴµ¥ »ç¿ëµÇ´Â ä³ÎÀÌ´Ù. ¿¹ÀüºÎÅÍ Áö±Ý±îÁö ¿À·§µ¿¾È À¯´Ð½º¿Í À©µµ¿ì NT¿¡¼ °í¼º´É I/O ÀÛ¾÷À» À§ÇØ vectored IO·Î ¾Ë·ÁÁø Scatter/Gather¸¦ »ç¿ëÇØ¿Ô´Ù. SCSI ÄÁÆ®·Ñ·¯ ¶ÇÇÑ ÀüüÀûÀÎ ¼º´É Çâ»óÀ» À§Çؼ Scatter/Gather¸¦ »ç¿ëÇÑ´Ù. ÀÚ¹Ù¿¡¼ ä³Îµµ Scatter/Gather¸¦ »ç¿ëÇϴµ¥, À̰ÍÀº ä³ÎÀÇ io ÀÛ¾÷¿¡ ´ëÇØ ¼º´É Çâ»óÀ» À§Çؼ Scatter/Gather ¿ÀÆÛ·¹À̼ǵéÀ» OS·Î ºü¸£°Ô Àü´ÞÇÔÀ¸·Î½á ³×ÀÌÆ¼ºê OS ¼öÁØÀÇ Ã³¸®¸¦ ÇÏ´Â °ÍÀÌ´Ù.
// Gather ¿¹.
ByteBuffer header = ByteBuffer.allocateDirect(32);
ByteBuffer body = ByteBuffer.allocateDirect(100)
ByteBuffer attach = ByteBuffer.allocateDirect(100);
ByteBuffer[] gatherBuffers = { header, body, attach };
gatherChannel.write(gatherBuffers);
nio ÆÐŰÁö¸¦ ÀÌ¿ëÇØ¼ ¼¹ö¸¦ ¸¸µé ¶§ °¡Àå ¸ÕÀú ÀÌÇØ¸¦ ¿ä±¸ÇÏ´Â ºÎºÐÀº SelectableChannel, Selector, SelectionKey ÀÌ ¼¼ °³ÀÇ Å¬·¡½º °£ÀÇ Çù·Â°ü°èÀÌ´Ù. ÀÌ ¼¼ °³ÀÇ Å¬·¡½º°¡ ¼·Î ¾î¶² ½ÄÀ¸·Î ¿¬°üµÇ¾î ¾î¶»°Ô »óÈ£ ÀÛ¿ëÇÏ´ÂÁö¸¦ ÀÌÇØÇÏ¸é ³ª¸ÓÁö ±â´É¿¡ ´ëÇÑ °ÍµéÀº API¸¦ ÅëÇØ ½±°Ô »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·³ ¸ÕÀú SelectableChannel¿¡ ´ëÇØ ¾Ë¾Æº¸ÀÚ.
¼ÒÄÏ °è¿ ä³ÎÀÇ ½´ÆÛ Ŭ·¡½º, SelectableChannel

<±×¸² 6> SelectableChannel °èÃþµµ
<±×¸² 6>¿¡¼ ³ªÅ¸³ªµíÀÌ SelectableChannelÀº ServerSocketChannel°ú SocketChannelÀÇ ½´ÆÛ Ŭ·¡½ºÀÌ´Ù. »Ó¸¸ ¾Æ´Ï¶ó ¼¹ö ÇÁ·Î±×·¡¹Ö¿¡¼ ¼ÒÄÏ Åë½ÅÀ» À§ÇØ »ç¿ëÇÒ ´Ù¸¥ ¸ðµç ä³ÎµéÀÌ »ó¼ÓÇϴ Ŭ·¡½ºÀÌ´Ù. ÀÌÇØ¸¦ ½±°Ô Çϱâ À§ÇØ SelectableChannelÀÇ API¸¦ »ìÆìº¸ÀÚ.
public abstract class SelectableChannel extends AbstractInterruptibleChannel
implements Channel {
public abstract SelectableChannel configureBlocking(boolean block);
public abstract SelectionKey register(Selector sel, int ops)
throws ClosedChannelException;
public abstract SelectionKey register(Selector sel, int ops, Object att)
throws ClosedChannelException;
...
}
SelectableChannel Ŭ·¡½º¿¡´Â Å©°Ô µÎ °¡ÁöÀÇ ÇÙ½ÉÀûÀÎ ¿ªÇÒÀ» ÇÏ´Â ¸Þ½îµå°¡ ÀÖ´Ù. ±× Áß Çϳª´Â ¼¹öÀÇ ºí·¯Å· ¿©ºÎ¸¦ °áÁ¤ÇÏ´Â configureBlocking ¸Þ½îµåÀ̰í, ´Ù¸¥ Çϳª´Â ÁÖ¾îÁø ÆÄ¶ó¹ÌÅÍÀÇ Selector¿¡ ÀÚ½ÅÀÌ ¾î¶² ¿ÀÆÛ·¹À̼Ç(ops)À» ÇÒÁö µî·ÏÇÏ´Â register ¸Þ½îµåÀÌ´Ù. À̶§ ÁÖÀÇÇÒ Á¡Àº ¹Ýµå½Ã register ¸Þ½îµå·Î Selector¿¡ µî·ÏÇϱâ Àü¿¡ ¸ÕÀú configureBlockingÀ¸·Î ¼¹öÀÇ ºí·¯Å· ¿©ºÎ¸¦ Á¤ÇØÁà¾ß ÇÑ´Ù. SelectableChannelÀº µðÆúÆ®·Î ºí·¯Å· ¸ðµå(true)°¡ ÁöÁ¤ µÅ ÀÖ´Ù. register ¸Þ½îµå¿¡ µÎ ¹øÂ° ÆÄ¶ó¹ÌÅÍ·Î µé¾î°¡´Â ops´Â <Ç¥ 2>¿¡¼Ã³·³ ³× °¡Áö°¡ ÀÖ´Ù.
<Ç¥ 2> operationµé°ú ±× ¿ªÇÒ
| ±¸ºÐ
| ³»¿ë
|
| OP_ACCEPT
| Ŭ¶óÀÌ¾ðÆ®°¡ ServerSocketChannel¿¡ Á¢¼ÓÀ» ½ÃµµÇßÀ» ¶§ ¹ß»ý
|
| OP_CONNECT
| ¼¹ö°¡ Ŭ¶óÀ̾ðÆ®ÀÇ Á¢¼ÓÀ» Çã¶ôÇßÀ» ¶§ ¹ß»ý
|
| OP_READ
| ¼¹ö°¡ Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÀ» readÇÒ ¼ö ÀÖÀ» ¶§ ¹ß»ý
|
| OP_WRITE
| ¼¹ö°¡ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô ÀÀ´äÀ» writeÇÒ ¼ö ÀÖÀ» ¶§ ¹ß»ý
|
SelectableChannelÀ» »ó¼ÓÇÑ ServerSocketChannel µîÀº register ¸Þ½îµå·Î ÀÚ½ÅÀ» Selector¿¡ µî·ÏÇØ¾ßÇϴµ¥ À̶§ ¸ðµç ops¸¦ »ç¿ëÇØ¼ µî·ÏÇÒ ¼ö´Â ¾ø´Ù. °¢ÀÚ µî·ÏÇÒ ¼ö ÀÖ´Â ops°¡ <Ç¥ 3>¿¡¼Ã³·³ Á¦ÇѵŠÀֱ⠶§¹®ÀÌ´Ù.
<Ç¥ 3> SelectableChannel µéÀÇ µî·Ï °¡´ÉÇÑ ops
| ±¸ºÐ
| ³»¿ë
|
| ServerSocketChannel
| OP_ACCEPT
|
| SocketChannel
| OP_CONNECT, OP_READ, OP_WRITE
|
| DatagramChannel
| OP_READ, OP_WRITE
|
| Pipe.SourceChannel
| OP_READ
|
| Pipe.SinkChannel
| OP_WRITE
|
register ¸Þ½î´Â Selector¿Í ops ¿Ü¿¡ ƯÁ¤ °´Ã¼¸¦ °°ÀÌ µî·ÏÇÒ ¼ö ÀÖ´Â register(Selector sel, int ops, Object att)µµ Á¦°øÇØÁִµ¥, ÀÌ ¸Þ½îµå¸¦ ÀÌ¿ëÇÏ¸é Æ¯Á¤ Ŭ¶óÀ̾ðÆ®ÀÇ ¼¼¼Ç, ºñÁî´Ï½º ·ÎÁ÷ ¶Ç´Â ´Ù¸¥ ä³Î µîÀ» ÇØ´ç ä³Î°ú ¿¬°ü½ÃÄѼ °£ÆíÇÏ°Ô »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª ÀÌ·¸°Ô ÇÔ²² µî·ÏµÈ °´Ã¼´Â ÇØ´ç ä³ÎÀÌ Á¾·áµÇ´õ¶óµµ Á¦°ÅµÇÁö ¾ÊÀ¸¹Ç·Î ¹Ýµå½Ã ä³Î Á¾·á ½Ã ¸í½ÃÀûÀ¸·Î Á÷Á¢ Á¦°ÅÇØÁà¾ß¸¸ ¸Þ¸ð¸® ³¶ºñ¸¦ ¸·À» ¼ö ÀÖ´Ù. ±×¸®°í SelectableChannelÀº ¿©·¯ Selector¿¡ µî·ÏÇÒ ¼ö ÀÖÁö¸¸ ÇϳªÀÇ Selector¿¡´Â ƯÁ¤ SelectableChannelÀÌ ÇÑ °³¸¸ µî·ÏµÈ´Ù. ¶ÇÇÑ SelectableChannelÀ» Selector¿¡ µî·ÏÇÒ ¶§ SelectableChannelÀÌ Selector¿¡ Á÷Á¢ ÀúÀåµÇ´Â °ÍÀº ¾Æ´Ï´Ù. register ¸Þ½îµåÀÇ ¸®ÅÏ °ªÀ» º¸°í ¸î¸î µ¶ÀÚºÐÀº ÁüÀÛÇß°ÚÁö¸¸ Selector¿¡ µî·ÏÇÒ ¶§ SelectionKey¶ó´Â °´Ã¼°¡ »ý¼ºµÇ°í ÀÌ °´Ã¼¸¦ Selector ³»ºÎÀÇ Set¿¡ ÀúÀåÇØ¼ °ü¸®ÇÑ´Ù.
ServerSocket¿¡ ´ëÀÀÇÏ´Â ServerSocketChannel
ServerSocketChannel Àº ServerSocket°ú °°Àº ¿ªÇÒÀ» ÇÑ´Ù. ¼¹ö¿¡ ¿¬°á(connection)Çϱâ À§ÇÑ ¿äûÀ» ¹Þ¾Æ¼ ¿äûÇÑ Å¬¶óÀÌ¾ðÆ®¿Í ¼¹öÀÇ ¿¬°áÀ» ¸Î¾îÁÖ´Â °ÍÀÌ´Ù. ÀÌ ServerSocketChannelÀ» ¸¸µé±â À§Çؼ´Â ServerSocket°ú °°ÀÌ new¸¦ »ç¿ëÇØ¼ Á÷Á¢ÀûÀ¸·Î ¸¸µé ¼ö ¾ø°í open() ¸Þ½îµå¸¦ »ç¿ëÇØ¼ ¸¸µç´Ù. ÀÌ·¸°Ô »õ·Î ¸¸µç ServerSocketChannelÀº ¿ÀÇ »óÅÂÁö¸¸ bind(ip, port¿¡ ¿¬°á)µÇÁö´Â ¾Ê´Â´Ù. ServerSocketChannelÀ» bind½Ã۱â À§Çؼ´Â ServerSocketÀÇ bind()¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. »ý¼ºµÈ ServerSocketChannel¿¡¼ ServerSocketÀ» ServerSocketChannelÀÇ socket()¸¦ È£ÃâÇØ¼ ¾òÀº ÈÄ¿¡ ÀÌ ServerSocketÀÇ bind() ¸Þ½îµå¸¦ È£ÃâÇØ¼ bind ½ÃŰ´Â °ÍÀÌ´Ù. ¸¸¾à ServerSocketÀÇ ¿É¼ÇÀ» ¼³Á¤ÇϰíÀÚ ÇÑ´Ù¸é ¾Õ¿¡¼ ó·³ ¾òÀº ServerSocketÀ» ÀÌ¿ëÇØ¼ ÀÌÀü¿¡ ÇØ¿Ô´ø °Í°ú °°Àº ¹æ¹ýÀ¸·Î ¼³Á¤ÇØÁÙ ¼ö ÀÖ´Ù.
ServerSocketChannel ssc = ServerSocketChannel.open();
ServerSocket ss = ssc.socket();
// ÇÊ¿äÇÑ °æ¿ì ss¸¦ ÀÌ¿ëÇØ¼ ServerSocket ¿É¼Ç ¼³Á¤.
InetAddress ia = InetAddress.getLocalHost();
InetSocketAddress isa = new InetSocketAddress(ia, PORT);
ss.bind(isa);
ServerSocketChannel¿¡¼ Ŭ¶óÀ̾ðÆ®ÀÇ ¿¬°á ¿äûÀ» ¹Þ¾Æ ¼¹ö¿Í ¿¬°áÀ» ¸Î¾îÁÖ±â À§Çؼ´Â ServerSocket°ú °°ÀÌ accept() ¸Þ½îµå¸¦ »ç¿ëÇÑ´Ù. ÇÏÁö¸¸ return °ªÀº ¼ÒÄÏÀÌ ¾Æ´Ï¶ó SocketChannelÀÌ´Ù.
SocketChannel sc = ssc.accept();
¼ÒÄÏ¿¡ ´ëÀÀÇÏ´Â SocketChannel
SocketChannelÀº ¼ÒÄϰú ºñ½ÁÇÏ°Ô Å¬¶óÀÌ¾ðÆ®¿Í Á÷Á¢ÀûÀÌ°í ½ÇÁúÀûÀÎ Åë½ÅÀ» ÇÑ´Ù. ÇÏÁö¸¸ ¼ÒÄϰú ´Þ¸® µ¥ÀÌÅ͸¦ ÁÖ°í¹ÞÀ» ¶§ read(ByteBuffer bb)/write(ByteBuffer bb) ¸Þ½îµå¸¦ »ç¿ëÇÑ´Ù. SocketChannelÀ» »ý¼ºÇÏ´Â °ÍÀº ´ÙÀ½°ú °°ÀÌ ¼¼ °¡Áö ¹æ¹ýÀÌ ÀÖ´Ù.
? ¿¬°áµÇÁö ¾ÊÀº SocketChannelÀÌ ¸¸µé¾îÁö´Â °æ¿ì
SocketChannel sc = SocketChannel.open();
? ÁÖ¾îÁø SocketAddress·Î Á¢¼ÓÇÏ´Â SocketChannelÀÌ ¸¸µé¾îÁö´Â °æ¿ì
SocketChannel sc = SocketChannel.open(SocketAddress remote);
? ¼¹ö¿¡ Á¢¼ÓÇÑ Å¬¶óÀÌ¾ðÆ®¿Í ¿¬°áµÈ SocketChnnelÀÌ ¸¸µé¾îÁö´Â °æ¿ì
SocketChannel sc = ServerSocketChannel.accept();
¶ÇÇÑ ServerSocketChannel°ú ¸¶Âù°¡Áö·Î socket() ¸Þ½îµå·Î ¼ÒÄÏÀ» ¾ò¾î¿Ã ¼ö ÀÖ°í ÀÌ·¸°Ô ¾òÀº ¼ÒÄÏÀ¸·Î ¿É¼ÇÀ» ¼³Á¤ÇÒ ¼ö ÀÖ´Ù.
Socket s = sc.socket();
// ÇÊ¿äÇÑ °æ¿ì s¸¦ ÀÌ¿ëÇØ¼ Socket ¿É¼Ç ¼³Á¤.
¸¶¹ýĸ½¶ SelectionKey
SelectionKey´Â ƯÁ¤ ä³Î°ú selector »çÀÌÀÇ µî·Ï °ü°è¸¦ ĸ½¶ÈÇÑ´Ù. Áï, ¾î¶² SelectableChannelÀÌ Æ¯Á¤ Selector¿¡ register()·Î µî·ÏÇÏ¸é ±×µéÀÇ ¿¬°ü °ü°è¸¦ Ç¥ÇöÇÏ´Â SelectionKey °´Ã¼°¡ »ý¼ºµÇ°í, ÀÌ °´Ã¼´Â Selector¿Í ¾ÖÇø®ÄÉÀ̼ÇÀÌ °¢°¢ÀÇ ¿ªÇÒÀ» ¼öÇàÇϴµ¥ »ç¿ëµÈ´Ù. ÀÌ·¸°Ô »ý¼ºµÈ °´Ã¼´Â µÎ °¡ÁöÀÇ ÇÙ½ÉÀûÀÎ ¿ªÇÒÀ» ÇÏ´Â setÀ» °®°í ÀÖ´Ù. ù ¹øÂ°´Â SelectableChannelÀÌ register()·Î Selector¿¡ µî·ÏÇÑ ¿ÀÆÛ·¹À̼ǵé(ops)À» ÀúÀåÇÏ´Â interest setÀÌ´Ù. µÎ ¹øÂ°´Â SelectableChannel¿¡¼ À̺¥Æ®°¡ ¹ß»ýÇÏ¸é ±× À̺¥Æ®µéÀ» ÀúÀåÇÏ´Â ready setÀÌ´Ù. ±×·³ API¸¦ »ìÆìº¸ÀÚ.
public abstract class SelectionKey {
public static final int OP_READ = 1 << 0; // => 1
public static final int OP_WRITE = 1 << 2; // => 4
public static final int OP_CONNECT = 1 << 3; //=> 8
public static final int OP_ACCEPT = 1 << 4; // => 16
public abstract int readyOps();
public boolean isAcceptable();
public boolean isConnectable();
public boolean isReadable();
public boolean isWritable();
public abstract void cancel();
public abstract SelectableChannel channel();
public abstract Selector selector();
}
SelectionKey ¿¡´Â API¿¡¼ º¼ ¼ö ÀÖµíÀÌ SelectableChannelÀÌ µî·ÏÇÒ ¼ö ÀÖ´Â ³× °³ÀÇ ¿ÀÆÛ·¹À̼ÇÀÌ static Çʵå·Î Á¤ÀǵŠÀÖ´Ù. ¶Ç readyOps()À¸·Î ÀÌ SelectionKey °´Ã¼°¡ ĸ½¶ÈÇϰí ÀÖ´Â SelectableChannelÀÌ À̺¥Æ®°¡ ¹ß»ýµÆ´ÂÁö¸¦ üũÇÒ ¼ö ÀÖ´Ù. À̰ÍÀº ´ÙÀ½°ú °°ÀÌ µÎ °¡Áö ¹æ½ÄÀ¸·Î °¡´ÉÇÏ´Ù. ´ÙÀ½ÀÇ ºÎºÐÀº Accept ¿ÀÆÛ·¹À̼ÇÀ» üũÇÏ´Â °ÍÀε¥ º¸´Ù½ÃÇÇ ´Ù¸¥ ¿ÀÆÛ·¹À̼ǵ鵵 ¾î¶»°Ô ÀÌ·ïÁúÁö ½±°Ô ÁüÀÛÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.
if (key.isAcceptable())
or
if ((key.readyOps() & SelectionKey.OP_ACCEPT) != 0)
¶ÇÇÑ channel() ¸Þ½îµå¿Í selector() ¸Þ½îµå·Î SelectableChannel°ú SelectorÀÇ ÀνºÅϽº¸¦ ¸®ÅÏ °ªÀ¸·Î ¹ÞÀ» ¼ö ÀÖ´Ù.
SocketChannel sc = key.channel();
Selector selector = key.selector();
cancel() ¸Þ½îµå´Â ÇØ´ç SelectionKey°¡ ĸ½¶ÈÇϰí ÀÖ´Â Selector¿Í SelectableChannelÀÇ °ü°è¸¦ Á¾·á½ÃŲ´Ù. Áï, SelectableChannel°¡ Selector¿¡¼ µî·ÏÇØÁ¦ µÇ´Â °ÍÀÌ´Ù. ±×¸®°í ±× SelectionKey´Â À¯È¿ÇÏÁö ¾Ê°Ô µÈ´Ù. ¸¸¾à ¾î¶² SelectableChannelÀÌ closeµÇ¸é ÀÌ SelectableChannelÀÌ µî·ÏÇÑ ¸ðµç Selector¿¡¼ Áï½Ã ÇØ´ç SelectionKey°¡ À¯È¿ÇÏÁö ¾Ê°Ô µÇ°í ÀûÀýÇÑ ½ÃÁ¡¿¡¼ µî·ÏÇØÁ¦ µÈ´Ù. ¿©±â¼ ÁÖÀÇÇØ¾ß ÇÒ °ÍÀº cancel() ¸Þ½îµå¸¦ È£ÃâÇϰųª SelectableChannelÀÌ closeµÆ´Ù°í ±× Áï½Ã Selector¿¡¼ µî·ÏÇØÁ¦ µÇ´Â °ÍÀÌ ¾Æ´Ï°í SelectorÀÇ cancelled key set¿¡ ³Ö¾îÁö°Ô µÈ´Ù. ÇÏÁö¸¸ ±× SelectionKey´Â Áï½Ã À¯È¿ÇÏÁö ¾Ê°Ô µÈ´Ù. ÀÌ·¸°Ô À¯È¿ÇÏÁö ¾Ê°Ô µÈ SelectionKeyÀÇ ¾î¶² ¸Þ½îµå¸¦ È£ÃâÇϸé CancelledKeyExceptionÀÌ ¹ß»ýÇÑ´Ù.
À̺¥Æ® Áß°èÀÚ Selector
1996³â¿¡ ÃâÆÇµÈ POSA2(Pattern Oriented Software Architecture, Volume2)¿¡ Reactor ÆÐÅÏÀÌ ¼Ò°³µÆ´Ù. Reactor ÆÐÅÏÀº À̺¥Æ® Á᫐ ¾ÖÇø®ÄÉÀ̼ÇÀÌ Çϳª ÀÌ»óÀÇ Å¬¶óÀÌ¾ðÆ®·ÎºÎÅÍ ÇÑ ¾ÖÇø®ÄÉÀ̼ÇÀ¸·Î µ¿½Ã¿¡ Àü´ÞµÇ´Â ¼ºñ½º ¿äûµéÀ» ³ª´² °¢ ¿äû¿¡ »óÀÀÇÏ´Â ¼ºñ½º Á¦°øÀÚ¿¡°Ô·Î ±¸º°Çؼ º¸³»ÁØ´Ù. Á» ´õ ÀÚ¼¼ÇÏ°Ô ¼³¸íÇϸé Ŭ¶óÀÌ¾ðÆ®µéÀÇ ¸ðµç ¿äûÀ» ¿ì¼± ¾Õ´ÜÀÇ Å¥¿¡ ÀúÀåÇϰí Å¥¸¦ ¸ð´ÏÅ͸µÇÏ´Â ¾²·¹µå¿¡°Ô À̺¥Æ®¸¦ º¸³½´Ù. ±×·¯¸é Å¥¸¦ ¸ð´ÏÅ͸µÇÏ´Â ¾²·¹µå´Â Å¥¿¡ ÀúÀåµÈ ¿äûÀÇ ¹æÇâÀ» ºÐ¼®Çؼ ÀûÀýÇÑ ÇÁ·Î¼¼½º·ÎÁ÷À¸·Î º¸³»ÁÖ¾î ÇØ´ç ¿äûÀÌ Ã³¸®µÇµµ·Ï ÇØÁÖ´Â °ÍÀÌ´Ù.
nio¿¡¼ ºñµ¿±â½Ä ¼¹ö ±¸ÇöÀÇ ¹Ø¹ÙÅÁÀÌ µÇ´Â °ÍÀÌ ¹Ù·Î Reactor ÆÐÅÏÀÌ´Ù. Selector´Â ¹Ù·Î Reactor ¿ªÇÒÀ» ÇÑ´Ù. Áï, ¿©·¯ SelectableChannelÀ»(´õ Á¤È®È÷ ¸»ÇÏÀÚ¸é ±× Ã¤³Î°úÀÇ °ü°è¸¦ Ç¥ÇöÇÏ´Â SelectionKey¸¦) Àڽſ¡°Ô µî·ÏÇÏ°Ô ÇÏ°í µî·ÏµÈ SelectableChannelÀÇ À̺¥Æ® ¿äûµéÀ» ³ª´² ÀûÀýÇÑ ¼ºñ½º Á¦°øÀÚ¿¡°Ô º¸³»¾î ó¸®ÇÏ´Â °ÍÀÌ´Ù.
Selector´Â ³»ºÎÀûÀ¸·Î ¼¼ °³ÀÇ setÀ» °ü¸®ÇÑ´Ù. ù ¹øÂ°´Â Àڽſ¡°Ô µî·ÏÇÑ SelectableChannelÀÇ SelectionKey¸¦ ÀúÀåÇÏ´Â Registered key setÀÌ´Ù. µÎ ¹øÂ°´Â selection ¸Þ½îµå(select(), select(long timeout), selectNow()) Áß Çϳª¸¦ È£ÃâÇßÀ» ¶§ Registered key set¿¡ µî·ÏµÈ SelectableChannel Áß¿¡¼ À̺¥Æ®°¡ ¹ß»ýÇÑ °ÍµéÀÇ SelectionKey¸¦ ÀúÀåÇÏ´Â Selected key setÀÌ´Ù. ¼¼ ¹øÂ°´Â Selector¿¡¼ µî·ÏÇØÁ¦Çϱâ À§ÇØ SelectionKeyÀÇ cancel() ¸Þ½îµå¸¦ È£ÃâÇϰųª SelectableChannelÀÇ close() ¸Þ½îµå¸¦ È£ÃâÇÑ SelectionKey¸¦ ÀúÀåÇÏ´Â Cancelled key setÀÌ´Ù.
Selector ¿ª½Ã SelectableChannelÀÇ ¼ºê Ŭ·¡½ºÃ³·³ open() ¸Þ½îµå¸¦ »ç¿ëÇØ »ý¼ºÇϰí close() ¸Þ½îµå¸¦ »ç¿ëÇØ Á¾·áÇÑ´Ù. ±×¸®°í wakeup() ¸Þ½îµå´Â select()³ª select(long timeout) ¸Þ½îµåÀÇ È£Ãâ·Î ºí·°µÈ ¾²·¹µå¸¦ ±ú¿ì´Âµ¥ »ç¿ëµÈ´Ù.
Selectorµµ ä³Î°ú Buffer Ŭ·¡½ºµé°ú ¸¶Âù°¡Áö·Î ³×ÀÌÆ¼ºê ¸Þ½îµå¸¦ »ç¿ëÇØ¼ ºü¸¥ 󸮸¦ ÇÑ´Ù.
nio ¼¹öÀÇ ÀüüÀûÀΠó¸® È帧
<±×¸² 7> Àº ºñµ¿±â½Ä ¼¹öÀÇ Àüü ±¸Á¶¸¦ º¸¿©ÁØ´Ù.

<±×¸² 7> ºñµ¿±â½Ä ¼¹ö ¾ÆÅ°ÅØÃ³
SelectableChannelÀº ÀÚ½ÅÀÌ ¹ß»ý½ÃŰ°í ½ÍÀº ¿ÀÆÛ·¹À̼ǰú ÇÔ²² Selector¿¡ µî·ÏÇÑ´Ù. ±×·¯¸é SelectorÀÇ Registered key set¿¡´Â ÇØ´ç SelectableChannelÀÇ Á¤º¸¸¦ ĸ½¶ÈÇϰí ÀÖ´Â SelectionKey°¡ ÀúÀåµÇ°í, ¸¸¾à ÀÌ·¸°Ô µî·ÏµÈ SelectableChannel¿¡¼ ¾î¶² À̺¥Æ®°¡ ¹ß»ýÇÏ¸é °ð¹Ù·Î ¾ÖÇø®ÄÉÀ̼Ç(Selector¸¦ ÀÌ¿ëÇØ À̺¥Æ®¸¦ ó¸®ÇÏ´Â ¼¹ö)¿¡ ¾Ë¸®Áö ¾Ê°í ¹ß»ýÇÑ À̺¥Æ®µéÀ» ÇØ´ç SelectionKeyÀÇ ready set¿¡ ±â·ÏÇØµÐ´Ù.
±×·± ÈÄ¿¡ ¾ÖÇø®ÄÉÀ̼ÇÀÌ SelectorÀÇ selection ¸Þ½îµå Áß Çϳª¸¦ È£ÃâÇßÀ» ¶§ ¸ÕÀú Cancelled key set ¾ÈÀÇ SelectionKey¸¦ µî·ÏÇØÁ¦ÇÏ°í ±× setÀ» ºñ¿ì°Ô µÈ´Ù. ±× ´ÙÀ½ Selector´Â ³»ºÎÀÇ Registered key set¿¡ ÀúÀåµÈ SelectionKey¸¦ °Ë»çÇÑ´Ù. À̶§ SelectionKeyÀÇ ready setÀÌ empty°¡ ¾Æ´Ñ(À̺¥Æ®°¡ ¹ß»ýÇÑ) SelectionKeyµéÀ» selected key set ¿¡ ³Ö´Â´Ù. ´ÙÀ½À¸·Î ¾ÖÇø®ÄÉÀ̼ÇÀÌ SelectorÀÇ selectedKeys() ¸Þ½îµå¸¦ È£ÃâÇØ¼ Selector¿¡ ÀúÀåµÈ selected key setÀ» °¡Á®¿À°í ±× ¾È¿¡ ÀúÀåµÈ °¢°¢ÀÇ SelectionKeyÀÇ ¿ÀÆÛ·¹ÀÌ¼Ç Å¸ÀÔ¿¡ µû¶ó ó¸®ÇÑ´Ù. ´ÙÀ½ÀÇ ¼Ò½º´Â nioServerÀÇ ÇÙ½ÉÀûÀΠó¸® ºÎºÐÀÌ´Ù(Àüü ¼Ò½º´Â ¡®ÀÌ´ÞÀÇ µð½ºÄÏ¡¯¿¡ ÷ºÎÇß´Ù).
while (true) {
int n = selector.select();
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
if (key.isAcceptable()) {
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel sc = server.accept();
boolean isRegist = registerChannel(selector, sc, SelectionKey.OP_READ);
if (isRegist)
room.addElement(sc);
} else if (key.isReadable()) {
service(key);
}
it.remove();
}
}
nio·Î ºñµ¿±â½Ä ¼¹ö¸¦ ¸¸µé ¶§ °í·ÁÇÒ Á¡
? ÇÁ·Î¼¼½º ·ÎÁ÷À» ThreadPool·Î ó¸®ÇÏ°Ô ¸¸µé¾î¶ó.
µ¿½Ã¿¡ ¸¹Àº 󸮸¦ ¿äÇÏ´Â ÇÁ·Î±×·¥¿¡¼ ¾²·¹µå´Â ÇʼöÀûÀ¸·Î »ç¿ëµÈ´Ù. 100¸íÀÇ °ü°´ÀÌ ¿µÈ ƼÄÏÀ» »ç±â À§ÇØ ÇϳªÀÇ Ã¢±¸¸¦ ÀÌ¿ëÇÏ´Â °Í°ú 10°³ÀÇ Ã¢±¸¸¦ ÀÌ¿ëÇÏ´Â °ÍÀº ºÐ¸í ¸¹Àº Â÷À̰¡ ÀÖ´Ù. °á±¹ ¸¹Àº ¾çÀÇ µ¿½Ã 󸮸¦ ¿ä±¸ÇÏ´Â ¼¹ö ÇÁ·Î±×·¥¿¡¼µµ ¼º´É Çâ»óÀ» À§ÇØ ¹Ýµå½Ã ±âº»ÀûÀ¸·Î ±¸ÇöÇØ¼ »ç¿ëÇØ¾ß ÇÏ´Â °ÍÀÌ ThreadPoolÀÌ´Ù.
? direct ByteBuffer¸¦ »ç¿ëÇØ¶ó.
ä³Î¿¡ direct ¹öÆÛ·Î writeÇÑ °æ¿ì¿¡´Â ³×ÀÌÆ¼ºê È£ÃâÀ» À§ÇØ Áï½Ã Àü´ÞµÇÁö¸¸, nondirect ¹öÆÛ·Î write¸¦ Çϸé ä³ÎÀº »õ·Î¿î direct ¹öÆÛ¸¦ ¸¸µé¾î¼ nondirect ¹öÆÛ¿¡ ÀÖ´ø µ¥ÀÌÅ͸¦ »õ·Î ¸¸µç direct ¹öÆÛ·Î º¹»çÇØ¼ Àü´ÞÇÑ´Ù. À̰ÍÀº µ¥ÀÌÅÍ º¹»ç¿¡ µû¸¥ ½Ã°£ Áö¿¬°ú °¡ºñÁö »ý¼º, »õ·Î¿î direct ¹öÆÛÀÇ »ý¼ºÀ¸·Î ÀÎÇÑ ½Ã°£ Áö¿¬ ¹× ¸Þ¸ð¸® ³¶ºñ¸¦ ÀǹÌÇÑ´Ù. ±×·¯¹Ç·Î ä³ÎÀ» ÀÌ¿ëÇÒ ¶§´Â ¹Ýµå½Ã direct ¹öÆÛ¸¦ »ç¿ëÇϰí direct ¹öÆÛÀÇ ÇÒ´ç ÇØÁ¦´Â ½Ã°£ÀÌ °É¸®´Â ÀÛ¾÷À̹ǷΠȿÀ²À» À§ÇØ direct ByteBufferPoolÀ» ¸¸µé¾î¼ »ç¿ëÇÏ´Â °ÍÀÌ ¹Ù¶÷Á÷ÇÏ´Ù.
? SelectorPoolÀ» ¸¸µé¾î¼ »ç¿ëÇØ¶ó.
À©µµ¿ì OSÀÇ °æ¿ì ÇϳªÀÇ Selector°¡ 63°³±îÁöÀÇ SelectableChannelÀ» µî·ÏÇÒ ¼ö ÀÖ´Ù. ´Ù¸¥ OSÀÇ °æ¿ì Integer.MAX_VALUE(2147483647)±îÁö µî·ÏÀÌ °¡´ÉÇÏ´Ù. ÇÏÁö¸¸ È¿À²À» À§ÇØ ÇϳªÀÇ ¾²·¹µå°¡ ÇϳªÀÇ Selector¸¦ °ü¸®ÇÏ´Â SelectorPoolÀ» ¸¸µé¾î¼ ¿©·¯ °³ÀÇ Selector¿¡ SelectableChannelµéÀ» ±ÕµîÇÏ°Ô µî·ÏÇØ¼ ¸ÖƼ ¾²·¹µå 󸮸¦ Çϵµ·Ï »ç¿ëÇÏ´Â °ÍÀÌ ¹Ù¶÷Á÷ÇÏ´Ù.
? SelectorÀÇ ³»ºÎ key set¿¡ ´ëÇÑ ¸ÖƼ ¾²·¹µå Á¢±ÙÀ» ÁÖÀÇÇ϶ó.
Selector´Â ¾²·¹µå¿¡ ´ëÇØ ¾ÈÀüÇÏÁö¸¸ SelectorÀÇ key setÀº ±×·¸Áö ¸øÇÏ´Ù. SelectorÀÇ ³»ºÎ key setÀº private Á¢±ÙÀÚ¸¦ °®°í ÀÖ´Â ³»ºÎ Çʵ带 Á÷Á¢ÀûÀ¸·Î ÂüÁ¶Çϱ⠶§¹®¿¡ ¸¸¾à ¾î¶² ¾²·¹µå°¡ key setÀ» ó¸®ÇÏ´Â µµÁß¿¡ ´Ù¸¥ ¾²·¹µå°¡ ±× key setÀ» º¯°æÇÏ¸é ¿¹»óÇÏÁö ¸øÇÒ °á°ú°¡ ¹ß»ýÇÒ ¼öµµ ÀÖÀ¸¹Ç·Î ÁÖÀÇÇØ¾ß ÇÑ´Ù.
|
nio¿¡ Ä£¼÷ÇØÁö±æ ¹Ù¶ó¸ç¡¦
¾Õ¼µµ °è¼Ó °Á¶ÇßÁö¸¸ ¼¹ö ÇÁ·Î±×·¥¿¡¼ ÃÖ¿ì¼± °í·Á ´ë»óÀº ¹Ù·Î È¿À²ÀÌ´Ù. ±×·±µ¥ Áö¸é°ü°è»ó Á÷Á¢ ¼Ò½º¸¦ ¼³¸íÇÏÁö ¸øÇßÀ¸¸ç, ÇÊÀÚ°¡ ¿¹Á¦·Î ¸¸µé¾î ÷ºÎÇÑ ¼¹ö¿¡¼´Â ¸î °¡Áö °³¼±ÇÒ Á¡ÀÌ ÀÖ´Ù. ºñ·Ï ¿ì¸®°¡ ¸¸µç ¼¹ö°¡ ºñµ¿±â½Ä ¼¹öÀÌÁö¸¸ ¾îµð±îÁö³ª Ŭ¶óÀÌ¾ðÆ®µéÀÇ ¼¹ö¿¡ ´ëÇÑ Connection°ú C/S°£ µ¥ÀÌÅÍ Àü¼Û¿¡ ´ëÇÑ ºí·¯Å·ÀÌ ¾ø¾úÀ» »ÓÀÌ°í ±× Ã³¸® ·ÎÁ÷Àº ¼øÂ÷Àû 󸮸¦ ÇÏ´Â ¹æ½ÄÀ̾ú´Ù. ±×·¯¹Ç·Î ù ¹øÂ° °³¼±Á¡Àº ÇÁ·Î¼¼½º ·ÎÁ÷À» ¾²·¹µå(È¿À²À» À§ÇØ ThreadPoolÀ» ¸¸µé¾î »ç¿ë)¸¦ »ç¿ëÇØ¼ µ¿½Ã¿¡ º´·Ä󸮸¦ ÇÔÀ¸·Î½á È¿À²À» ³ô¿©¾ß ÇÏ´Â °ÍÀÌ´Ù.
µÎ ¹øÂ°´Â ByteBufferPoolÀ» ¸¸µé¾î »ç¿ëÇÔÀ¸·Î½á direct ByteBufferPoolÀÇ ÇÒ´ç?ÇØÁ¦ÇÏ´Â ½Ã°£À» Àý¾àÇÏ´Â °ÍÀÌ´Ù. ¿©±â¼ Á» ´õ ³ª¾Æ°¡ OS°¡ Çϵåµð½ºÅ©¸¦ °¡»ó ¸Þ¸ð¸®·Î ¼³Á¤Çؼ »ç¿ëÇϵíÀÌ FileChannelÀ» ÀÌ¿ëÇØ¼ ¸Þ¸ð¸® ºÎÁ· ½Ã ÆÄÀÏÀ» ¸Þ¸ð¸®·Î »ç¿ëÇϵµ·Ï ¸¸µé ¼ö ÀÖ´Ù. ´ÙÀ½ È£¿¡¼´Â ¾Õ¼ ¿ì¸®°¡ ¸¸µç äÆÃ ¼¹ö¿¡ À§¿¡¼ ¾ð±ÞÇÑ ThreadPool°ú ByteBufferPoolÀ» Ãß°¡½ÃÄÑ È¿À² ±Ø´ëÈ¿Í ¸Þ¸ð¸® ºÎÁ·¿¡ ÀÇÇÑ ¼¹ö ´Ù¿îÀ» ÃÖ´ëÇÑ ¿¹¹æÇÒ ¼ö ÀÖ´Â °ß°íÇÑ ¼¹ö¸¦ ¸¸µé¾îº¸ÀÚ.
¸¶¼Ò¿¡ ±â»ç¸¦ ¾²´Â ´Ù¸¥ ÇÊÀÚµéÀÇ ±ÛÀ» ÀÐÀ» ¶§ ¸¹Àº ºÐÀÌ Á¦ÇÑµÈ Áö¸é ¶§¹®¿¡ ÇÏ°í ½ÍÀº ¸»À» Á¦´ë·Î ¾²Áö ¸øÇß´Ù¸ç ¾Æ½¬¿öÇÏ´Â°É ºÁ¿Ô´Ù. Áö±Ý ÀÌ·¸°Ô ±â»ç¸¦ ¾²¸é¼ ³ª ¶ÇÇÑ ±× ºÐµé°ú °°Àº »ý°¢À» ÇÏ°Ô µÈ´Ù. Á¦ÇÑµÈ Áö¸é°ü°è»ó ¼³¸íÇÏÁö ¸øÇÑ ºÎºÐ°ú Á» ´õ ÀÚ¼¼ÇÏ°Ô ¼³¸íÇÏ°í ½ÍÁö¸¸ ±×·¸Áö ¸øÇÑ ºÎºÐµéÀÌ ÀÖ¾î¼ ¸¹Àº ¾Æ½¬¿òÀÌ ³²´Â´Ù. ÇÏÁö¸¸ ³ª¸§´ë·Î ÃÖ¼±À» ´ÙÇØ ½±°Ô ¼³¸íÇÏ·Á°í ³ë·ÂÇßÀ¸¹Ç·Î ¸¹Àº µ¶ÀÚµéÀÌ º» ±â»ç¸¦ ÅëÇØ nio¿¡ Á» ´õ Ä£¼÷ÇØÁø´Ù¸é ±×°Í¸¸À¸·Îµµ Å« ±â»ÝÀÌ µÉ °ÍÀÌ´Ù. ´ÙÀ½ È£¿¡¼ ´õ ÁÁÀº ±Û·Î ã¾ÆºÉ °ÍÀ» ¾à¼Óµå¸®¸ç À̸¸ ±ÛÀ» ¸¶¹«¸®ÇϰڴÙ.
Á¤¸® : Á¶±ÔÇü ( jokyu@korea.cnet.com )
Âü°íÀÚ·á
1. Java Nio by Ron Hitchens, 2002 O'reilly
2. http://www.onjava.com/pub/a/onjava/2002/10/02/javanio.html
3. http://www.onjava.com/pub/a/onjava/2002/09/04/nio.html
4. http://java.sun.com/j2se/1.4/docs/guide/nio/index.html
5. http://developer.java.sun.com/developer/technicalArticles/releases/nio
6. http://www.javaworld.com/javaworld/jw-09-2001/jw-0907-merlin.html
7. ¼Ò½º ÀÚ·á