|
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°¡ ÇÒ´çµÇ´Â
°ÍÀ» º¸ÀåÇØ ÁØ´Ù.
|