.
.
.
 
2003³â 12¿ù 12ÀÏ  


Core Java Technologies Tech Tips¿¡ ¿À½Å ¿©·¯ºÐÀ» ȯ¿µÇÕ´Ï´Ù. Java 2 Platform, Standard Edition (J2SE)¿¡ ±â¹ÝÇÑ core Java technologies ¿Í APIsÀÇ »ç¿ë¿¡ °üÇÑ ÃֽŠÁ¤º¸¸¦ ¾ò¾î °¡½Ã±â ¹Ù¶ø´Ï´Ù. ÀÌ ±Û¿¡¼­´Â Java 2 SDK, Standard Edition, v 1.4¸¦ »ç¿ëÇÕ´Ï´Ù.

À̹ø È£¿¡¼­´Â,

-½ºÀ®¿¡¼­ÀÇ ¸ÖƼ¾²·¹µù
-¾²·¹µåÀÇ »óÅÂÁ¤º¸¸¦ ÀúÀåÇÒ ¶§ »ç¿ëµÇ´Â THREADLOCAL º¯¼öµé

À» ´Ù·ç°Ô µË´Ï´Ù.

ÀúÀÚ John Zukowski

.
.

½ºÀ®¿¡¼­ÀÇ ¸ÖƼ ¾²·¹µù

½ºÀ® ÄÄÆ÷³ÍÆ® ¼¼Æ®´Â ´ç½Ã¿¡ Java Development Kit (JDK)·Î ¾Ë·ÁÁ³´ø 1.1¹öÀü°ú ÇÔ²² »ç¿ëµÇµµ·Ï 1996³â¿¡ óÀ½ ¼Ò°³µÇ¾ú´Ù. ½ºÀ® ÄÄÆ÷³ÍÆ® ¼¼Æ®´Â ±×·¡ÇÈ »ç¿ëÀÚ È¯°æ(GUI, Graphical User Interface)À» °³¹ßÇϱâ À§ÇØ »ç¿ëµÇ´Â Abstract Window Toolkit (AWT) ÄÄÆ÷³ÍÆ® ¼¼Æ®ÀÇ ´ë¾ÈÀ¸·Î Á¦°øµÇ¾úÀ¸¸ç ÇöÀçµµ Á¦°øµÇ°í ÀÖ´Ù. AWT´Â ¸ðµç Ç÷§Æû»ó¿¡¼­ »ç¿ëÀÚ È¯°æ(UI)À» Ç¥ÇöÇÏ´Â ÄÄÆ÷³ÍÆ®µé Áß ÃÖ¼ÒÇÑÀÇ °øÅë ¿ä¼Ò¸¸À» ±¸ÇöÇÑ °ÍÀ¸·Î Ç÷§Æûº°·Î ³»ÀçÇϰí ÀÖ´Â µµ±¸¿¡ ÀÇÁ¸ÇÑ °ÍÀÌ´Ù. Foundation Classes (JFC)ÀÇ ÇѺκÐÀ¸·Î¼­ ½ºÀ® ÄÄÆ÷³ÍÆ® ¼¼Æ®´Â ¼ø¼öÇÏ°Ô ÀÚ¹Ù Å×Å©³î·ÎÁö¿¡ ±â¹ÝÇÑ ¼Ö·ç¼ÇÀ¸·Î½á, ¸ðµç µå·ÎÀ× ÄÚµå(È­¸é¿¡ ÄÄÆ÷³ÍÆ®¸¦ ±×¸®´Â ÄÚµå)°¡ ÀÚ¹Ù Ç÷§Æû ³»ºÎ¿¡ Á¸ÀçÇÑ´Ù.

°ÅÀÇ ¸ðµç ½ºÀ® ÄÄÆ÷³ÍÆ® ¼¼Æ®¿¡ °üÇÑ Æ©Å丮¾ó¿¡¼­ ÄÄÆ÷³ÍÆ® ¼¼Æ®´Â ½Ì±Û ¾²·¹µå·Î ¼³¸íµÈ´Ù. Áï, "±¸ÇöµÈ(realized)" ÄÄÆ÷³ÍÆ®¿¡ ´ëÇÑ ¸ðµç ¾×¼¼½ºµéÀº ¹Ýµå½Ã À̺¥Æ® µð½ºÆÐÄ¡ ¾²·¹µå·Î(event dispatch thread)ºÎÅÍ ÀÌ·ç¾îÁ®¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù. "±¸ÇöµÈ"À̶ó´Â ¸»Àº º»·¡ ½ºÅ©¸°¿¡ µð½ºÇ÷¹À̵ȴٴ °ÍÀ» ÀǹÌÇÑ´Ù. ½ÇÁ¦·Î À̰ÍÀº ½ºÀ® ÄÄÆ÷³ÍÆ®¸¦ ½ºÅ©¸°¿¡ ³ªÅ¸³»±â Àü¿¡ ½ºÅ©¸°À» ±¸ÃàÇϰí ÇÊ¿äÇÑ ¼Ó¼ºµéÀ» ¹Þ¾Æ ¼³Á¤ÇÏ´Â °ÍÀÌ °¡´ÉÇÏ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. ´ÙÀ½ Swing1ÇÁ·Î±×·¥Àº ÇÁ·¹ÀÓ¿¡ ¹öưÀ» Ãß°¡ÇÑ ÈÄ À̸¦ µð½ºÇ÷¹ÀÌÇϰí ÀÖ´Ù.

   import javax.swing.*;
   import java.awt.*;

   public class Swing1 {
     public static void main(String args[]) {
       JFrame frame = new JFrame();
       frame.setTitle("Title");
       frame.setDefaultCloseOperation(
         JFrame.EXIT_ON_CLOSE);
       JButton button = new JButton();
       button.setText("Hello, World!");
       frame.getContentPane().add(button,
         BorderLayout.CENTER);
       frame.setSize(200, 100);
       frame.show();
      }
   }

ÀÌ °£´ÜÇÑ ÇÁ·Î±×·¥À» º¸¸é º° ¹®Á¦°¡ ¾ø´Ù°í »ý°¢ÇÒ ¼ö ÀÖ´Ù. ½ÇÁ¦ÀûÀ¸·Î ÀÌ¿Í ºñ½ÁÇÑ ÇÁ·Î±×·¥µéÀÌ ½ºÀ®¿¡ °üÇÑ Æ©Å丮¾óÀ̳ª Core Java Technologies Tech Tips¿Í °°Àº ¾ÆÆ¼Å¬¿¡¼­ Á¦°øµÇ°í ÀÖ´Ù. ÇÏÁö¸¸ °£´ÜÇÏ´Ù°í ÇØ¼­ ´Ù ¸Â´Â °ÍÀº ¾Æ´Ï´Ù. À§ÀÇ ÇÁ·Î±×·¥¿¡µµ À߸øµÈ Á¡ÀÌ ÀÖ´Ù.

¿©±â¼­ ¹üÀÎÀº show ¸Þ¼ÒµåÀÇ È£ÃâÀÌ´Ù. Á»´õ Á¤È®ÇÏ°Ô ¼³¸íÇÏÀÚ¸é, ÄÁÅ×À̳ʸ¦ packingÇÏ´Â ¸Þ¼Òµå¸¦ À¯¹ßÇÏ´Â setVisible(true)ÀÇ ¼û°ÜÁø È£ÃâÀÌ ¹®Á¦ÀÌ´Ù. setVisible°ú pack¸ðµÎ ÇÁ·¹ÀÓ¿¡ ¿¬°üµÈ ÇǾî(peer)¸¦ »ý¼ºÇÒ °ÍÀÌ´Ù. ÇǾîÀÇ »ý¼º°ú ÇÔ²², ½Ã½ºÅÛÀº À̺¥Æ® µð½ºÆÐÄ¡ ¾²·¹µå¸¦ »ý¼ºÇÑ´Ù. ÇÏÁö¸¸ pack°ú validate°¡ 󸮵ǰí ÀÖ´Â µ¿¾È À̺¥Æ® µð½ºÆÐÄ¡ ¾²·¹µå°¡ ´Ù¸¥ ¾î¶² À̺¥Æ®°¡ ÀϾÀ½À» ¸®½º³Ê¿¡°Ô ÅëÁöÇÏ´Â °æ¿ì¿¡ ¹®Á¦°¡ »ý±æ ¼ö ÀÖ´Ù. ÀÌ·¯ÇÑ »óȲÀº GUI¿¡ ±â¹ÝÇÑ ½ºÀ® ÄÄÆ÷³ÍÆ®¸¦ ó¸®ÇÏ´Â 2°³ÀÇ ¾²·¹µå¸¦ ¹ß»ýÇÏ°Ô ÇÑ´Ù. À̰ÍÀº ±³Âø»óÅÂ(deadlock)³ª ¾²·¹µù°ú °ü·ÃÇÑ ¹®Á¦¸¦ ¾ß±âÇÒ ¼ö Àֱ⠶§¹®¿¡ ½É°¢ÇÑ °áÇÔÀ̶ó ÇÒ ¼ö ÀÖ´Ù. pack È£ÃâÀº ÄÄÆ÷³ÍÆ®¸¦ ±¸ÇöÇϴµ¥, ÄÄÆ÷³ÍÆ®µéÀÌ ±¸ÇöµÇ¸é¼­(ÀÌ ¶§ ²À ½Ã°¢ÀûÀ¸·Î º¼ ¼ö ÀÖÀ» ÇÊ¿ä´Â ¾ø´Ù.) À̺¥Æ® µð½ºÆÐÄ¡ ¾²·¹µå¿¡ ¸®½º³Ê ÅëÁö¸¦ À¯¹ßÇÒ ¼ö ÀÖ´Ù.

ÀÌ ¹®Á¦¸¦ ¾î¶»°Ô ÇØ°áÇÒ °ÍÀΰ¡? °£´ÜÇÑ ¹æ¹ýÀº main ¾²·¹µå¿¡¼­ ÇÁ·¹ÀÓÀ» º¸¿©ÁÖ´Â show¸¦ »ç¿ëÇÏÁö ¾Ê´Â °ÍÀÌ´Ù. ÀÌ °æ¿ì¿¡µµ ¸ðµç GUI »ý¼ºÀ» À§ÇÑ ÄÚµå´Â main ¾²·¹µå ³»¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª âÀ» È­¸é¿¡ º¸ÀÌ°Ô ÇÏ´Â ½ÃÁ¡ÀÌ µÇ¸é, ÀÌ·¯ÇÑ ÄÚµå´Â À̺¥Æ® µð½ºÆäÄ¡ ¾²·¹µå¿¡¼­ ÀÛ¾÷ÇÏ´Â °ÍÀÌ´Ù. À̰ÍÀº ´Ü ÇϳªÀÇ ¾²·¹µå¸¸ÀÌ ½ºÀ® ÄÄÆ÷³ÍÆ®¸¦ ÃʱâÈ­ÇÑ´Ù´Â °ÍÀ» º¸ÁõÇÑ´Ù.

ÀÌÇϰ¡ ¾²·¹µå¿¡ ¾ÈÀüÇϵµ·Ï ÀçÀÛ¼ºÇÑ ÀÌÀüÀÇ »ùÇà ÇÁ·Î±×·¥ÀÌ´Ù.

   import javax.swing.*;
   import java.awt.*;
   import java.lang.reflect.*;

   public class Swing2 {
      private static class FrameShower 
                                  implements Runnable {
        final Frame frame;
        public FrameShower(Frame frame) {
          this.frame = frame;
        }
        public void run() {
          frame.show();
        }
      }
      public static void main(String args[]) {
        JFrame frame = new JFrame();
        frame.setTitle("Title");
        frame.setDefaultCloseOperation(
          JFrame.EXIT_ON_CLOSE);
        JButton button = new JButton();
        button.setText("Hello, World!");
        frame.getContentPane().add(button,
          BorderLayout.CENTER);
        frame.setSize(200, 100);
        Runnable runner = new FrameShower(frame);
        EventQueue.invokeLater(runner);
      }
   }

¿ø·¡ÀÇ ¿¹Á¦¿Í ºñ±³ÇØ º¸¸é, ¹Ù²ï ÄÚµå´Â ´ÜÁö Runnable Ŭ·¡½º¸¦ »ý¼ºÇϱâ À§ÇÑ °ÍÀÌ´Ù.

   private static class FrameShower 
                               implements Runnable {
     final Frame frame;
     public FrameShower(Frame frame) {
       this.frame = frame;
     }
     public void run() {
       frame.show();
     }
   }
     ...
     Runnable runner = new FrameShower(frame);

±×¸®°í³ª¼­ Runnable °´Ã¼¸¦ invokeLater ³ª invokeAndWait ¸Þ¼Òµå·Î ³Ñ±âÀÚ.

   EventQueue.invokeLater(runner);

È£ÃâÀÌ ¹Ù¸£°Ô ÀÌ·ç¾îÁö¸é, ÀÌ °á°ú´Â ¿¹Á¦ ÇÁ·Î±×·¥ÀÇ thread-safe ¹öÀüÀÌ µÈ´Ù. ¸¸¾à ÇÁ·Î±×·¥µéÀÌ ½ºÀ®³»ÀÇ ¾²·¹µùÀ» ºÎÀûÀýÇÏ°Ô ´Ù·ç°í ÀÖ´Ù¸é, ÇÁ·Î±×·¥À» °ËÅäÇØº¸°í ¾÷µ¥ÀÌÆ®¸¦ °í·ÁÇØº¸ÀÚ.

¾²·¹µå¿Í ½ºÀ®¿¡ °üÇÑ ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â ÀÚ¹Ù Æ©Å丮¾óÀÇ Threads ¿Í Swing trailÀ» Âü°íÇÑ´Ù.

.
.

¾²·¹µåÀÇ »óÅÂÁ¤º¸¸¦ ÀúÀåÇÒ ¶§ »ç¿ëµÇ´Â THREADLOCAL º¯¼öµé

ƯÁ¤ ¾²·¹µåÀÇ ½ºÄÚÇÁ¿¡¼­ »ç¿ëÇÒ ·ÎÄú¯¼ö°¡ ÇÊ¿äÇß´ø ÀûÀÌ Àִ°¡? À̶§¿¡ °¢°¢ÀÇ ¾²·¹µå´Â °íÀ¯ÀÇ ½ºÅ丮Áö¸¦ °®°í ÇϳªÀÇ ¾²·¹µå´Â ´Ù¸¥ ¾²·¹µåÀÇ »óÅ Á¤º¸¸¦ ¾×¼¼½ºÇÏ´Â °ÍÀÌ ºÒ°¡´ÉÇÒ °ÍÀÌ´Ù. Ç¥ÁØ ¶óÀ̺귯¸®´Â ÀÌ·¯ÇÑ ¿ä±¸¸¦ °¡´ÉÄÉ ÇÏ´Â ThreadLocal °ú InheritableThreadLocal, 2°³ÀÇ Å¬·¡½ºµéÀ» Á¦°øÇϰí ÀÖ´Ù.

Ŭ·¡½ºµéÀÌ »ç¿ëµÇ°í ÀÖ´Â ¿¹¸¦ º¸ÀÚ.

  import java.util.Random;

  public class ThreadLocal1 {

    // Define/create thread local variable
    static ThreadLocal threadLocal = 
                                   new ThreadLocal();
    // Create class variable
    static volatile int counter = 0;
    // For random number generation
    static Random random = new Random();

    // Displays thread local variable, counter, 
    // and thread name
    private static void displayValues() {
      System.out.println (
        threadLocal.get() + "\t" + counter +
        "\t" + Thread.currentThread().getName());
    }

    public static void main (String args[]) {

      // Each thread increments counter
      // Displays variable info
      // And sleeps for the random amount of time
      // Before displaying info again
      Runnable runner = new Runnable() {
        public void run() {
          synchronized(ThreadLocal1.class) {
            counter++;
          }
          threadLocal.set(
             new Integer(random.nextInt(1000)));
          displayValues();
          try {
            Thread.currentThread().sleep (
              ((Integer)threadLocal.get()).intValue());
            displayValues();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      };

      // Increment counter, access thread local from 
      // a different thread, and display the values
      synchronized(ThreadLocal1.class) {
          counter++;
      }
      threadLocal.set(
         new Integer(random.nextInt(1000)));
      displayValues();

      // Here's where the other threads
      //  are actually created
      for (int i=0; i<5; i++) {
        Thread t = new Thread(runner);
        t.start();
      }
    }
  }

ThreadLocal1Ŭ·¡½º´Â 2°³ÀÇ Á¤Àû º¯¼ö¸¦ °®´Â´Ù. common integer primitive ŸÀÔÀÎ counter¿Í ThreadLocal ŸÀÔÀÇ º¯¼öÀÎ threadLocalÀÌ ¹Ù·Î ±×°ÍÀÌ´Ù. ÀϹÝÀûÀ¸·Î Ŭ·¡½º º¯¼ö¸¦ »ç¿ëÇϸé, ÇØ´ç Ŭ·¡½ºÀÇ ¸ðµç ÀνºÅϽºµéÀº µ¿ÀÏÇÑ °ªÀ» °øÀ¯ÇÏ°Ô µÈ´Ù. ÇÏÁö¸¸ ThreadLocalÀÇ °æ¿ì´Â ´Ù¸£´Ù. ThreadLocalŬ·¡½º¸¦ »ç¿ëÇÏ¸é µ¿ÀÏÇÑ ¾²·¹µå³»¿¡¼­¸¸ °°Àº Á¤Àû Á¤º¸¸¦ °øÀ¯ÇÏ°Ô µÇ´Â ¹Ý¸é, ¼­·Î ´Ù¸¥ ¾²·¹µå¿¡¼­ ThreadLocal Ŭ·¡½º¸¦ »ç¿ëÇÏ¸é ¼­·Î ´Ù¸¥ Á¤Àû Á¤º¸¸¦ °®°Ô µÈ´Ù.

ThreadLocal1¿¡¼­, ThreadLocal ÀνºÅϽº´Â 0¿¡¼­ 999»çÀÌÀÇ ·£´ýÇÑ ¼ýÀÚ·Î ÃʱâÈ­µÈ´Ù.

   threadLocal.set(
     new Integer(random.nextInt(1000)));

´Ù¼öÀÇ ¼­·Î ´Ù¸¥ ¾²·¹µå°¡ »ý¼ºµÇ¾ú´Ù. °¢°¢ÀÇ ¾²·¹µå º°·Î, 2°³ÀÇ Å¬·¡½º º¯¼ö¿¡ ´ëÇÑ »óÅ Á¤º¸°¡ µð½ºÇ÷¹À̵ȴÙ. ±×·¯¸é ÀÌ ¾²·¹µå´Â ThreadLocalÀÌ ·£´ýÇÑ ¼ýÀÚ·Î ÁöÁ¤ÇÑ ¸¸Å­ÀÇ ¹Ð¸®Ãʵ¿¾È ÈÞ¸éÇÑ´Ù. ÀÌÈÄ, 2°³ÀÇ Å¬·¡½º º¯¼öÀÇ »óÅ Á¤º¸°¡ ´Ù½Ã µð½ºÇ÷¹À̵ǰí, ThreadLocal1¸¦ ½ÇÇàÇϸé, ¾Æ·¡¿Í °°Àº Ãâ·Â°ªÀ» º¸°Ô µÈ´Ù.

   828     1       main
   371     2       Thread-0
   744     3       Thread-1
   734     4       Thread-2
   189     5       Thread-3
   790     6       Thread-4
   189     6       Thread-3
   371     6       Thread-0
   734     6       Thread-2
   744     6       Thread-1
   790     6       Thread-4

¿©±â¿¡¼­ ÁÖ¸ñÇÒ °ÍÀº ¼¼¹øÂ° Ä÷³¿¡¼­ ¾²·¹µåÀÇ À̸§ÀÌ °°À» ¶§¸¦ »ìÆìº¸¸é, ù¹øÂ° Ä÷³ÀÇ ThreadLocal º¯¼ö°ªÀÌ ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÇ´Â µ¿¾È °°Àº »óŸ¦ À¯ÁöÇÑ´Ù´Â °ÍÀÌ´Ù. ¹Ý¸é, µÎ¹øÂ° Ä÷³¿¡¼­ º¸ÀÌ´Â Á¤Àû º¯¼ö´Â ÇÁ·Î±×·¥ÀÌ ½ÇÇàÇÏ´Â µ¿¾È º¯È­Çϰí, ±âÁ¸ ¾²·¹µå¸¦ Àç°ËÅäÇÒ ¶§ ±× ¹Ù²ï °ªÀ» À¯ÁöÇÑ´Ù. À̰ÍÀÌ ¹Ù·Î ÀûÀýÇÏ°Ô µ¿±âÈ­µÈ Á¤Àû º¯¼ö°¡ ÇØ¾ß ÇÏ´Â ÀÏÀÌ´Ù.

ÇÁ·Î±×·¥À» ½ÇÇàÇÒ ¶§¸¶´Ù ¸ðµç Ä÷³¿¡´Â °¢±â ´Ù¸¥ °ªÀÌ »ý¼ºµÇ±â ¶§¹®¿¡ °á°ú¿¡¼­ º¸À̴ ù¹øÂ° Ä÷³ÀÇ ½Ã°£µéÀÌ À§¿¡¼­ º¸´Â ¹Ù¿Í ´Ù¸£´Ù°Å³ª, ¸¶Áö¸· 5°³ÀÇ ÇàÀÇ À̸§ÀÇ ¼ø¼­°¡ ´Ù¸£´Ù°í ÇØµµ ³î¶ö ÇÊ¿ä´Â ¾ø´Ù. ±× ¼ø¼­´Â ù¹øÂ° Ä÷³¿¡¼­ º¸¿©Áø ½Ã°£(times)¿¡ ±â¹ÝÇÑ °ÍÀÌ´Ù.

¾²·¹µå ·ÎÄà º¯¼ö´Â ´Ü¼øÈ÷ ÀνºÅϽº º¯¼öµéÀÇ ¶Ç ´Ù¸¥ ÇüŸ¸ÀÌ ¾Æ´Ï´Ù. ¸¸¾à ƯÁ¤ Ŭ·¡½ºÀÇ 10°³ÀÇ ÀνºÅϽº¸¦ ¸ðµÎ ÀϹÝÀûÀÎ ¾²·¡µå³»¿¡¼­ Á¢±ÙÇÑ´Ù¸é, ±×°ÍµéÀÇ ThreadLocal Á¤º¸´Â ¸ðµÎ °°À» °ÍÀÌ´Ù. ±×·¯³ª, ¸¸¾à ÀÌ·¯ÇÑ ÀνºÅϽºµé ÁßÀÇ Çϳª¸¦ ´Ù¸¥ ¾²·¹µå¿¡¼­ Á¢±ÙÇÏ°Ô µÇ¸é, ThreadLocal Á¤º¸´Â ¹Ù²î°Ô µÉ °ÍÀÌ´Ù.

ThreadLocal Ŭ·¡½º´Â ¿ÀÁ÷ 3°³ÀÇ ¸Þ¼Òµå¸¸À» Æ÷ÇÔÇϰí Àִµ¥ get, set°ú initialValue°¡ ¹Ù·Î ±×°ÍÀÌ´Ù. ThreadLocal1 ¿¹Á¦¸¦ º¸¸é, set¸Þ¼Òµå´Â ÀνºÅϽº°¡ »ý¼ºµÈ ÀÌÈÄ È£ÃâµÇ´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. ThreadLocalÀÇ »óŸ¦ ÀÌÈÄ¿¡ ´Ù½Ã ÃʱâÈ­ÇÏ´Â ¹æ¹ý ´ë½Å¿¡, ThreadLocalÀ» »ó¼ÓÇÑ ¼­ºêŬ·¡½º¿¡¼­ initialValue ¸Þ¼Òµå¸¦ ¿À¹ö¶óÀ̵åÇÒ ¼ö ÀÖ´Ù. ´ÙÀ½ÀÇ ThreadLocal2 Ŭ·¡½º°¡ ¹Ù·Î ±× ÀÏÀ» Çϴµ¥, »ý¼ºµÈ Ãâ·Â°ªÀº ThreadLocal1ÀÇ °æ¿ì¿Í ºñ½ÁÇÏ´Ù.

   import java.util.Random;

   public class ThreadLocal2 {

     // Create thread local class
     // Initial value is a random number from 0-999
     private static class MyThreadLocal
                                  extends ThreadLocal {
       Random random = new Random();
       protected Object initialValue() {
         return new Integer(random.nextInt(1000));
       }
     }

     // Define/create thread local variable
     static ThreadLocal threadLocal =
                           new MyThreadLocal();

     // Create class variable
     static volatile int counter = 0;

     // For random number generation
     static Random random = new Random();

     // Displays thread local variable, counter,
     // and thread name
     private static void displayValues() {
       System.out.println (
         threadLocal.get() + "\t" + counter +
         "\t" + Thread.currentThread().getName());
     }
    
     public static void main (String args[]) {

       // Each thread increments counter
       // Displays variable info
       // And sleeps for the random amount of time
       // Before displaying info again
       Runnable runner = new Runnable() {
         public void run() {
           synchronized(ThreadLocal2.class) {
             counter++;
           }
           displayValues();
           try {
             Thread.currentThread().sleep (
               ((Integer)threadLocal.get()).intValue());
             displayValues();
           } catch (InterruptedException e) {
             e.printStackTrace();
           }
         }
       };

       // Another instance of class created
       // and values displayed
       displayValues();

       // Here's where the other threads
       // are actually created
       for (int i=0; i<5; i++) {
         Thread t = new Thread(runner);
         t.start();
       }
     }
   } 

ThreadLocalÀÇ initialValue ¸Þ¼Òµå´Â °¢°¢ÀÇ ¾²·¹µå°¡ »óŸ¦ ¾Ë¾Æ³»±â À§ÇØ Çϴ ù¹øÂ° È£Ãâ¿¡¼­ »ç¿ëµÈ´Ù. SetÀÌ ÀÌ¹Ì È£ÃâµÈ »óŶó¸é, initialValue ¸Þ¼Òµå´Â Àý´ë·Î È£ÃâµÇÁö ¾Ê´Â´Ù. initialValue ¸Þ¼Òµå¸¦ »ç¿ëÇÒ ¶§, publicÀÌ ¾Æ´Ï¶ó protected·Î ¸¸µé¾î¾ß ÇÑ´Ù´Â °ÍÀ» ±â¾ïÇÏÀÚ. ÀϹÝÀûÀ¸·Î initialValue ¸Þ¼Òµå°¡ ÀÓÀǷΠȣÃâµÇ´Â °ÍÀº ¹Ù¶÷Á÷ÇÏÁö ¾Ê±â ¶§¹®ÀÌ´Ù. initialValue °¡ ¿À¹ö¶óÀ̵åµÇÁö ¾Ê¾ÒÀ» °æ¿ì, ¾²·¹µå ·ÎÄà º¯¼ö¸¦ ³ªÅ¸³»´Â °´Ã¼ÀÇ Ãʱ⠰ªÀº nullÀÌ´Ù.

ThreadLocalº¯¼ö¿¡ ´ãÀ» ÄÁÅÙÃ÷´Â ¾î¶² Object ŸÀÔÀ̵çÁö °¡´ÉÇÏ´Ù. ThreadLocal2¿¡¼­ ÄÁÅÙÃ÷´Â IntegerÀÌ´Ù. getÀ» ÀÌ¿ëÇØ¼­ »óŸ¦ ¹Þ¾Æ³¾ ¶§ Object¸¦ ÀûÀýÇÑ Å¸ÀÔÀ¸·Î ij½ºÆÃÇØ¾ß ÇÑ´Ù´Â °ÍÀ» ±â¾ïÇÏÀÚ.

InheritableThreadLocal¶ó°í ºÒ¸®´Â ThreadLocalÀÇ µÎ¹øÂ° ŸÀÔÀ» º¸ÀÚ. ThreadLocal°ú °°ÀÌ, InheritableThreadLocalÀ» »ç¿ëÇÏ´Â °¢°¢ÀÇ ¾²·¹µå´Â °íÀ¯ÀÇ »óŰ´Ã¼¸¦ °®´Â´Ù. ThreadLocal°ú InheritableThreadLocalÀÇ Â÷ÀÌÁ¡Àº InheritableThreadLocalÀÇ ÃʱⰪÀº »ý¼ºÇÏ´Â ¾²·¹µå·ÎºÎÅÍ º¯¼öÀÇ »óŸ¦ ¾ò¾î³½´Ù´Â µ¥¿¡ ÀÖ´Ù. »óÅÂÀÇ º¯°æÀº ´Ù¸¥ ¾²·¹µå¸¦ Á¦¿ÜÇÑ ·ÎÄà ¾²·¹µå¿¡¼­¸¸ °¡´ÉÇÏ´Ù. InheritableThreadLocalÀÇ »õ·Î¿î childValue ¸Þ¼Òµå´Â ±×°ÍÀÇ »óŸ¦ ÃʱâÈ­ÇϱâÀ§ÇØ »ç¿ëµÇ´Âµ¥ ÀÌ´Â »óŸ¦ ¾ò¾î³»·Á°í ÇÒ ¶§°¡ ¾Æ´Ï¶ó ÀڳఴüÀÇ »ý¼ºÀÚ¿¡ ÀÇÇØ È£ÃâµÈ´Ù.

½ÇÁ¦·Î ThreadLocalÀÇ »ç¿ëÀ» °ËÅäÇϱâ À§Çؼ­´Â, java.nio.charsetÀÇ Charset Ŭ·¡½º¸¦ º¸°Å³ª java.util.LoggingÀÇ LogRecord¸¦ Âü°íÇÑ´Ù. CharsetÀÇ °æ¿ì¿¡´Â, ThreadLocal°¡ ij¸¯ÅÍ ¼¼Æ® ÀÎÄÚ´õ¿Í µðÄÚ´õ¸¦ °Ë»öÇϱâ À§ÇØ »ç¿ëµÈ´Ù. À̰ÍÀº ÃʱâÈ­ÇÏ´Â ÄÚµåµéÀÌ ÀýÀýÇÑ ½Ã±â¿¡ »ç¿ëµÇµµ·Ï Á¶ÀýÇÏ´Â ¿ªÇÒÀ» ÇÑ´Ù. LogRecord¿¡¼­ ThreadLocalÀÇ »ç¿ëÀº °¢°¢ÀÇ ¾²·¹µå¿¡ LoginÀ» À§ÇÑ °íÀ¯ÇÑ id°¡ ÇÒ´çµÇ´Â °ÍÀ» º¸ÀåÇØ ÁØ´Ù.

.
.
.

Reader Feedback

  ¸Å¿ì ÁÁ´Ù    ÁÁ´Ù    ±×Àú ±×·¸´Ù 

 

ÀÚ¹Ù ÇÁ·Î±×·¡¹ÖÀÌ ±Ã±ÝÇϼ¼¿ä? Java Online SupportÀ» Âü°íÇϼ¼¿ä.

.
.
Sun Microsystems, Inc.
.
.