ìë°ì 겜ëì€ë ë 몚ëžìž Virtual Thread륌 íë² ì 늬íŽë³Œë €ê³ íë€. íë²ë ì ëë¡ ì¬ì©íŽë³ž 겜íì ìì§ë§ ê·žëë ê°ë ì ì 늬íŽëìŒë©Ž ëì€ì ì ì©íê² ë ìŒìŽ ìꞰ멎 ì¢ì§ ììê¹ ìê°íë€.
ê°ëšíê² íë¡ìžì€ì ì€ë ëì ì°šìŽì ì íë¡ìžì€ë ìŽì첎ì ë¡ë¶í° ììì í ë¹ë°ì ì€ííë ìì ì ëšì, ì€ë ëë íë¡ìžì€ë¡ë¶í° ììì í ë¹ë°ì ì€ííë íëŠ ëë ì€íì ëšì, íëì íë¡ìžì€ ëŽìì ì€ë ëë ìœë, ë°ìŽí°, í ììì ê³µì íê³ , ê°ê°ì ì€ë ëë ì€í ììì ê°ê³ ëìíë€. ê·žëì íëì íë¡ìžì€ëŽì ìë ì€ë ë ê°ìë ë³ëì êž°ì ììŽ ë°ìŽí° ê³µì ê° ê°ë¥íë€.
ìŒëš íë¡ìžì€ì ëíŽ ìì볎ì! ì°ëЬë íë¡ìžì€ë¥Œ ìœê² ë§í ë, ì€íì€ìž íë¡ê·žëš, ìŠ cpuì ìíŽ ë©ëªšëЬì ì¬ë €ì ž ì€íì€ìž íë¡ê·žëšì ë§íë€. ìë° JVMì ì£Œë¡ íëì íë¡ìžì€ë¡ ì€íëë©°, ëìì ì¬ë¬ ìì ì ìííêž° ìíŽ ë©í° ì€ë ë륌 ì§ìíë€.
| êµ¬ë¶ | íë¡ê·žëš | íë¡ìžì€ |
|---|---|---|
| ì ì | ì€íí ì ìë íìŒ (ì ì ìž ìí) | ë©ëªšëЬì ì ì¬ëìŽ ì€í ì€ìž íë¡ê·žëš |
| ìí | ì ì¥ ì¥ì¹ì ì ì¥ë ì ì ìž ìœë ë©ìŽëЬ | ë©ëªšëЬì ì ì¬ëê³ CPU ììì í ë¹ë°ì ì€í ì€ |
| ìì | .exe, .jar ë± ì€í ê°ë¥í íìŒ | íë¡ê·žëšìŽ ì€íëë ëì ë©ëªšëЬìì ì€íëë ìí |
| ê°ëší ì€ëª | ê·žë¥ ìœë ë©ìŽëЬ | ìœëê° ì€ì ë¡ ì€íëê³ ìë ìí |

Stack 곌 Heapììì íë¡ìžì€ê° ì€íëë ëì í¬êž°ê° ëìŽë¬ë€ ì€ìŽë€êž°ë íë ëì ìììŽë€.
íë¡ìžì€ê° ìì±ë ìí
fork(), exec() íšì륌 íµíŽ ìì±, ìŽë PCB í ë¹
ë©ëªšëЬ ê³µê°ìŽ ì¶©ë¶í멎 ë©ëªšëŠ¬ë¥Œ í ë¹ë°ê³ ìë멎 ìë ìíë¡ ëêž°íê³ ììŒë©°, CPU ì€ìŒì€ë¬ë¡ë¶í° CPU ìì ê¶ìŽ ëìŽì€êž°ë¥Œ êž°ë€ëЬë ìí
ë©ëªšëЬ ë¶ì¡±ìŒë¡ ìŒì ì€ëšë ìí
CPU ìì ê¶ê³Œ ë©ëªšëŠ¬ë¥Œ í ë¹ë°ê³ ìžì€ížëì ì ìí ì€ìž ìí륌 ì믞, ìŽë¥Œ CPU burstê° ìŒìŽë¬ë€ê³ ë íí
ìŽë€ ìŽë²€ížê° ë°ìí ìŽí, êž°ë€ëŠ¬ë©° íë¡ìžì€ê° ì°šëšë ìí
I/O ëë°ìŽì€ì ìí ìží°ëœížë¡ ìŽë° íììŽ ë§ìŽ ë°ìíêž°ë íë€.
ì€ëšë ìíìì íë¡ìžì€ê° ì€íë ë €ê³ íì§ë§ ë©ëªšëЬ ë¶ì¡±ìŒë¡ ìŒì ì€ëšë ìí
ë©ëªšëЬì CPU ìì ê¶ì 몚ë ëê³ ê°ë ìí륌 ë§íë€. ì¢ ë£ë ìì°ì€ëœê² ì¢ ë£ëë ê²ë ìì§ë§ ë¶ëªš íë¡ìžì€ê° ìì íë¡ìžì€ë¥Œ ê°ì ìí€ë ë¹ìë°ì ì¢ ë£(abort)ë¡ ì¢ ë£ëë ê²ë ìë€. ìì íë¡ìžì€ì í ë¹ë ììì íê³ì¹ë¥Œ ëìŽìê±°ë ë¶ëªš íë¡ìžì€ê° ì¢ ë£ëê±°ë ì¬ì©ìê° process, kill ë± ì¬ë¬ ëª ë ¹ìŽë¡ íë¡ìžì€ë¥Œ ì¢ ë£í ë ë°ì
ìŽì첎ì ìì íë¡ìžì€ì ëí ë©íë°ìŽí°ë¥Œ ì ì¥í 'ë°ìŽí°'
íë¡ìžì€ ì ìµ ëžë¡
íë¡ìžì€ê° ìì±ë멎 ìŽì첎ì ë íŽë¹ PCB ìì±
PCB륌 êµííë 곌ì , í íë¡ìžì€ì í ë¹ë ìê°ìŽ ëëê±°ë ìží°ëœížì ìíŽ ë°ì
컚í ì€íž ì€ìì¹ì ì íìíê°?
CPUë í ë²ì íëì íë¡ìžì€ë§ ì€íí ì ììŒë¯ë¡, ì¬ë¬ íë¡ìžì€/ì€ë ë륌 ëìì ì€íìí€êž° ìíŽì
ë©í° íë¡ìžì±
íëì íë¡ìžì€ìì ì€íëìŽìŒí ìì ë€ì ì¬ë¬ ê°ë¡ ë¶ëЬí íì ê°ê°ì CPU ìœìŽì ë£ìŽì ë³í ì€íëëë¡ íë êž°ë²
ì€ë ë ëŒëЬë íë¡ìžì€ì ììì ê³µì í멎ì íë¡ìžì€ì ì€í íëŠì ìŒë¶ê° ëê³ , ëì ìì ìŽ ê°ë¥íë€. ìŽë íë¡ìžì€ì 4ê°ì§ ë©ëªšëЬ ìì(Code, Data, Heap, Stack) ì€ ì€ë ëë Stackë§ í ë¹ë°ì ë³µì¬íê³ Code, Data, Heapì íë¡ìžì€ ëŽì ë€ë¥ž ì€ë ëë€ê³Œ ê³µì íë€.

ê°ê°ì ì€ë ëë ë³ëì stackì ê°ì§ì§ë§ heap ë©ëªšëЬë ê³ ì íêž° ë묞ì ìë¡ ë€ë¥ž ì€ë ëìì ê°ì žì ìšë ëë€.
ìŒë°ì ìŒë¡ íë¡ìžì€ì ë©ëªšëЬë ë³ëì ì ì¥ ê³µê°ìì ì€íëêž° ë묞ì ìë¡ ì ê·ŒìŽ ë¶ê°ë¥íë€. íì§ë§ í¹ë³í ë°©ë²ìŒë¡ ì 볎륌 ê³µì ê°ë¥íë€.
IPC(Inter-Process Communication)
LPC(Local inter-Process Communication)
ë³ëì ê³µì ë©ëªšëŠ¬ë¥Œ ë§ë€ìŽì ì 볎륌 ì£Œê³ ë°ëë¡ ì€ì
ìì ë¶ëŽìŽ í¬ë€ë ëšì ìŽ ì¡Žì¬íì¬, ë€ì€ ìì ìŽ íìí 겜ì°, ì€ë ë륌 ìŽì©íëê²ìŽ íšì¬ íšìšì ìŽë€.
íë¡ìžì€ê° ì€ì€ë¡ CPU ìì ê¶ì í¬êž°íë ë°©ì, ê°ì ë¡ íë¡ìžì€ ì€ì§íì§ ìëë€. ë°ëŒì 컚í ì€íž ì€ìì¹ìŒë¡ ìží ë¶íê° ì ë€.
ê°ì¥ 뚌ì ìšê²ì ê°ì¥ 뚌ì ì²ëЬíë ìê³ ëŠ¬ìŠ
ì€íìê°ìŽ ì§§ì íë¡ìžì€ë¥Œ ê°ì¥ 뚌ì ì€í
SJFì ꞎ ìê°ì ê°ì§ íë¡ìžì€ê° ì€íëì§ ìë íìì ë°©ì§íêž° ìíŽ ì€ëë ìì ìŒìë¡ ì°ì ìì륌 ëìŽë ë°©ë²
íë ìŽì첎ì ê° ì°ë ë°©ììŒë¡ ì§êž ì¬ì©íê³ ìë íë¡ìžì€ ìê³ ëŠ¬ìŠì ìíŽ ì€ëš ììŒë²ëŠ¬ê³ ê°ì ë¡ ë€ë¥ž íë¡ìžì€ì CPU ìì ê¶ì í ë¹íë ë°©ì
ê° íë¡ìžì€ë ëìŒí í ë¹ ìê°ì ì£Œê³ , ê·ž ìê°ìì ëëì§ ììŒë©Ž ë€ì ì€ë¹ í(ready queue)ì ë€ë¡ ê°ë ìê³ ëŠ¬ìŠ
SJFë ì€ê°ì ì€í ìê°ìŽ ë ì§§ì ìì ìŽ ë€ìŽìë Ʞ졎 ì§§ì ìì ì 몚ë ìííê³ , ê·ž ë€ì ì§§ì ìì ì ìŽìŽëê°ëë°, SRFë ì€ê°ì ë ì§§ì ìì ìŽ ë€ìŽì€ë©Ž ìííë íë¡ìžì€ë¥Œ ì€ì§íê³ íŽë¹ íë¡ìžì€ë¥Œ ì€ííë ìê³ ëŠ¬ìŠ
ì°ì ììì ë°ë¥ž ì€ë¹ í(Ready Queue)륌 ì¬ë¬ê° ì¬ì©íê³ , íë§ë€ RRìŽë FCFS ë± ë€ë¥ž ì€ìŒì€ë§ ìê³ ëŠ¬ìŠ ì ì©íë ê²
ìë°ë main() ë©ìëê° ììë멎ì Main Threadê° ì€íëë€. ìŽë¬í Main Thread íëŠ ììì ì±êž ì€ë ëê° ìë ë©í° ì€ë ëë¡ ìëíê³ íìíŽë°ëŒ ë ë€ë¥ž ìì ì€ë ë륌 ë§ë€ìŽ ë³ë ¬ë¡ ìœë륌 ì€í ê°ë¥íë€. ì±êž ì€ë ë멎, ë©ìž ì€ë ëê° ì¢ ë£ëë€ê³ ê°ì í멎, íë¡ìžì€ë ì¢ ë£ëì§ë§, ë©í° ì€ë ëë Main Threadê° ì¢ ë£ëëëŒë ì€íì€ìž ì€ë ëê° íëëŒë 졎ì¬íë€ë©Ž íë¡ìžì€ë ì¢ ë£ëì§ ìëë€.
ìë°ìì ì€ë ë륌 ë§ëë ë°©ë²ì 2ê°ì§ê° 졎ì¬íë€. íëë Thread íŽëì€ë¥Œ ìì ë°ë ë°©ë², ë íëë Runnable ìží°íìŽì€ë¥Œ 구ííë ë°©ë²
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread ì€í ì€...");
try {
Thread.sleep(2000); // 2ìŽê° ëêž°
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread ì¢
ë£!");
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // ì€ë ë ìì
}
}
class MyRunnableImpl implements Runnable {
@Override
public void run() {
System.out.println("MyRunnable ì€í ì€...");
try {
Thread.sleep(2000); // 2ìŽê° ëêž°
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("MyRunnable ì¢
ë£!");
}
public static void main(String[] args) {
MyRunnableImpl myRunnable = new MyRunnableImpl();
Thread thread = new Thread(() -> myRunnable.run()); // Runnableì ì€í
thread.start(); // ì€ë ë ìì
}
}
class CalculationTask extends Thread {
private int start, end;
public CalculationTask(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public void run() {
int sum = 0;
for (int i = start; i <= end; i++) {
sum += i;
}
System.out.println(Thread.currentThread().getName() + " ê³ì° ìë£, í©: " + sum);
}
public static void main(String[] args) {
Thread thread1 = new CalculationTask(1, 500);
Thread thread2 = new CalculationTask(501, 1000);
thread1.start(); // 첫 ë²ì§ž ì€ë ë ìì
thread2.start(); // ë ë²ì§ž ì€ë ë ìì
}
}
ì ìì ë 1ë¶í° 1000ê¹ì§ì í©ì ë ê°ì ì€ë ë륌 ì¬ì©íì¬ ë³ë ¬ë¡ ê³ì°íë ììë€. ê° ì€ë ëë ìì ì ë²ì ëŽìì ê³ì°ì ìííê³ , ë ì€ë ëê° ëìì ì€íëë¯ë¡ ì 첎 ê³ì° ìê°ìŽ ì ìœëë€. í¹í, ë³ë ¬ ì²ëЬë ëêž° ìê° ê°ìê° ì€ìí ì í늬ìŒìŽì ìì ì€ë ëë ë§€ì° ì ì©íë€.

ìì±ë ì€ë ëë€ì ìì ì í ë¹ë°êž° ìíŽ ëêž° ìíì ìëë°, ìì ìŽ ë°ìíë€ë©Ž ì€ë ë ì€ íë륌 ì ííì¬ ìì ì ìííë€. ìì ìŽ ìë£ëë€ë©Ž ëêž° ìíë¡ ê°ê³ , ìë¡ìŽ ìì ì í ë¹ ë°ì ì€ë¹ë¥Œ íë€.
ìŽë ê² ì°ë ë íì ì¬ì©íë€ë©Ž, ì€ë ë ìì± ë° ìì ì ë°ë¥ž ì€ë²í€ë륌 ì€ìŽë©°, í¹ì ìì ì ëìì ì²ëЬí ììë ìì ì ê°ì륌 ì íí ììë€. ë°ëŒì ìì€í ì ììì íšìšì ìŒë¡ êŽëЬíê³ ì±ë¥ì í¥ì ìí¬ ì ìë€.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
// ì€ë ë í ìì± (ìµë 5ê°ì ì€ë ë)
ExecutorService executorService = Executors.newFixedThreadPool(5);
// 10ê°ì ìì
ì ì ì¶ (ìŽ 10ê°ì ìì
ìŽ ì€ë ë íì ìíŽ ì²ëЬëš)
for (int i = 0; i < 10; i++) {
final int taskId = i;
executorService.submit(() -> {
System.out.println("ìì
" + taskId + " ìì - " + Thread.currentThread().getName());
try {
Thread.sleep(2000); // 2ìŽ ëì ëêž° (ìì
ì뮬ë ìŽì
)
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("ìì
" + taskId + " ìë£ - " + Thread.currentThread().getName());
});
}
// ìì
ìŽ ëªšë ìë£ë멎 ì€ë ë í ì¢
ë£
executorService.shutdown();
}
}
ìë°ì Ʞ졎 ì€ë ë 몚ëžì ì€ë ë íë§ìŒë¡ë ì²ëЬëì ë늬ëë° ìŽë €ìì 겪ìë€.

Ʞ볞ìë ìë°ì ì ì ì€ë ë륌 ë§ë€ë©Ž Java Native Interface(JNI)륌 íµíŽ ì»€ë ììì ížì¶íì¬ OSê° ì»€ë ì€ë ë륌 ìì±íê³ ë§€ííì¬ ìì ì ìííë ííìë€.
Java ì€ë ëë I/O, interrupt, sleep ë±ì ìí©ìì block/waiting ìíê° ëìŽ, ë€ë¥ž ì€ë ëê° ì»€ë ì€ë ë륌 ì ì íì¬ ìì ì ìííë â컚í ì€íž ì€ìì¹â륌 ë°ììíšë€. ì€ë ëë íë¡ìžì€ì ê³µíµ ììì ì ìží ë 늜ì ìž ì€í ëšìë¡, íë¡ìžì€ì ë¹íŽ í¬êž°ê° ìê³ ìì± ë¹ì©ìŽ ì ìŒë©° 컚í ì€íž ì€ìì¹ ë¹ì©ìŽ ë®ì íšìšì ìŽë€.
íì§ë§ ìë² í겜ìì ìì²ëìŽ êžìŠí멎ì ì€ë ë ìê° ë§ìì§ìë¡ ë©ëªšëЬ íê³ì 컚í ì€íž ì€ìì¹ ë¹ì©ìŽ ìŠê°íë 묞ì ê° ë°ìíë€. ì륌 ë€ìŽ, 1MB í¬êž°ì ì€ë ë륌 êž°ì€ìŒë¡ 4GB ë©ëªšëЬ í겜ììë ìµë 4,000ê°ì ì€ë ëë§ ìì±í ì ììµëë€.
ìŽë¬í 묞ì 륌 íŽê²°íêž° ìíŽ Virtual ThreadëŒë 겜ë ì€ë ë 몚ëžìŽ ë±ì¥íì¬, ë ë§ì ìì²ì ì²ëЬíê³ ì»ší ì€íž ì€ìì¹ ë¹ì©ì ì€ìŽë ë°©ë²ìŒë¡ 죌목ë°ê³ ìë€.

Virtual Threadë Ʞ졎 Javaì ì€ë ë 몚ëžê³Œ ë¬ëЬ, íë«íŒ ì€ë ëì ê°ì ì€ë ëë¡ ëëë€. íë«íŒ ì€ë ë ììì ì¬ë¬ Virtual Threadê° ë²ê°ì ê°ë©° ì€íëë ííë¡ ëìíë€. ë§ì¹ 컀ë ì€ë ëì ì ì ì€ë ëê° ë§€íëë ííë ë¹ì·íë€.
ì¬êž°ì ê°ì¥ í° í¹ì§ì Virtual Threadë 컚í ì€íž ì€ìì¹ ë¹ì©ìŽ ì ë Žíë€ë ê²ìŽë€.
ì°žê³ :