λͺ©μ°¨:
1. μ€λ λ(Thread)λ 무μμΈκ°?
2. μλ°μμμ μ€λ λ μ¬μ©λ²
3. μ€λ λ μ‘°μ(Manipulating Threads)
4. λ€μ€ μ€λ λ νκ²½μμμ λκΈ°ν(Synchronization)
5. μλ° μ€λ λ μμ
1. μ€λ λ(Thread)λ 무μμΈκ°?
μ€λ λ(Thread)λ νλ‘κ·Έλ¨ λ΄μμ λμμ μ€νλλ μΌλ ¨μ μμ λ¨μλ₯Ό λ§ν©λλ€. μ€λ λλ νλ‘μΈμ€ λ΄μμ λ 립μ μΌλ‘ μ€νλλ©°, λμμ μ¬λ¬ μμ μ μνν μ μμ΅λλ€.
μΌλ°μ μΌλ‘ νλ‘κ·Έλ¨μ μ€νν λ, νλ‘μΈμ€λ λ¨μΌ μ€λ λλ‘ μ€νλλ©° μμ μ μμ°¨μ μΌλ‘ μνλ©λλ€. νμ§λ§ μ€λ λλ₯Ό μ¬μ©νλ©΄ μ¬λ¬ μμ μ λμμ μ€νν μ μμΌλ―λ‘, λ€μ€ μ€λ λ νκ²½μμ νλ‘μΈμ€μ μ€ν μκ°μ μ€μ΄κ³ μ±λ₯μ ν₯μμν¬ μ μμ΅λλ€.
μ€λ λλ μμ μ μ€ν 컨ν μ€νΈ, μ€ν, λ μ§μ€ν° λ±μ κ°μ§λ©°, λ 립μ μΈ μ€ν νλ¦μ κ°κ³ μμ΅λλ€. λμΌν νλ‘μΈμ€ λ΄μμ μ¬λ¬ μ€λ λκ° λμμ μ€νλ μ μκ³ , κ° μ€λ λλ μλ‘ κ³΅μ λλ λ©λͺ¨λ¦¬ 곡κ°μ μ κ·Όνμ¬ λ°μ΄ν°λ₯Ό 곡μ ν μ μμ΅λλ€.
μ€λ λλ μ£Όλ‘ λ³λ ¬μ±μ νμ©νμ¬ λμμ μ¬λ¬ μμ μ μ²λ¦¬νκΈ° μν΄ μ¬μ©λ©λλ€. μλ₯Ό λ€μ΄, μΉ μλ²μμ ν΄λΌμ΄μΈνΈ μμ²μ λμμ μ²λ¦¬νλ κ²½μ°, κ° ν΄λΌμ΄μΈνΈ μμ²μ μ€λ λλ‘ μ²λ¦¬νμ¬ λ³λ ¬μ μΌλ‘ μ€νν μ μμ΅λλ€.
μ€λ λλ λ€μκ³Ό κ°μ μ₯μ μ κ°μ§κ³ μμ΅λλ€:
- λΉ λ₯Έ μλ΅ μκ°: μ¬λ¬ μμ μ λμμ μ²λ¦¬ν¨μΌλ‘μ¨ μλ΅ μκ°μ λ¨μΆμν¬ μ μμ΅λλ€.
- μμ 곡μ : μ¬λ¬ μ€λ λλ νλ‘μΈμ€ λ΄μμ λ©λͺ¨λ¦¬ 곡κ°μ 곡μ ν μ μμΌλ―λ‘, λ°μ΄ν° 곡μ μ ν¨μ¨μ μΈ μμ μ¬μ©μ΄ κ°λ₯ν©λλ€.
- κ²½μ μ±: μ€λ λλ νλ‘μΈμ€λ₯Ό μμ±νλ κ²λ³΄λ€ κ²½μ μ μΌλ‘ μμ± λ° κ΄λ¦¬νκΈ° λλ¬Έμ μμ€ν μμμ ν¨μ¨μ μΌλ‘ μ¬μ©ν μ μμ΅λλ€.
νμ§λ§ μ€λ λλ₯Ό μ¬μ©ν λ μ£Όμν΄μΌ ν λͺ κ°μ§ λ¨μ λ μμ΅λλ€:
- 볡μ‘μ±: μ€λ λλ₯Ό μ¬μ©νλ©΄ λμμ± λ¬Έμ μ λκΈ°ν λ¬Έμ λ± λ³΅μ‘ν μν©μ μ§λ©΄ν μ μμ΅λλ€.
- μνΈμμ© λ¬Έμ : μ¬λ¬ μ€λ λκ° λμμ λ©λͺ¨λ¦¬λ₯Ό μμ νλ κ²½μ°, λ°μ΄ν° μΌκ΄μ±μ μ μ§νκΈ° μν μ‘°μΉκ° νμν μ μμ΅λλ€.
- λ°λλ½: μ¬λ¬ μ€λ λκ° μνΈκ°μ μλ‘μ μμ μ κΈ°λ€λ¦¬λ μν©μ΄ λ°μνμ¬ λ¬΄ν λκΈ° μνμ λΉ μ§ μ μλ λ°λλ½(deadlock) λ¬Έμ κ° μμ μ μμ΅λλ€.
μ€λ λλ₯Ό ν¨κ³Όμ μΌλ‘ νμ©νκΈ° μν΄μλ λκΈ°ν λ¬Έμ μ μνΈμμ© λ¬Έμ λ₯Ό κ³ λ €νκ³ μ μ ν μμ 곡μ κΈ°λ²μ μ¬μ©νμ¬ λ€μ€ μ€λ λ νκ²½μ κ΄λ¦¬ν΄μΌ ν©λλ€.
2. μλ°μμμ μ€λ λ μ¬μ©λ²
μλ°μμ μ€λ λλ₯Ό μ¬μ©νκΈ° μν΄ java.lang.Thread
ν΄λμ€λ₯Ό μ¬μ©ν©λλ€. Thread
ν΄λμ€λ μ€λ λμ μμ± λ° μ μ΄μ μ¬μ©λλ©°, λ€μκ³Ό κ°μ λ°©λ²μΌλ‘ μ¬μ©ν μ μμ΅λλ€.
μ€λ λ μμ±
μ€λ λλ₯Ό μμ±νκΈ° μν΄μλ Thread
ν΄λμ€λ₯Ό μμλ°μμ μλ‘μ΄ ν΄λμ€λ₯Ό μ μνκ±°λ, Runnable
μΈν°νμ΄μ€λ₯Ό ꡬννλ λ°©λ²μ μ¬μ©ν μ μμ΅λλ€.
1. Thread
ν΄λμ€λ₯Ό μμλ°μ λ°©λ²:
public class MyThread extends Thread {
public void run() {
// μ€λ λμμ μ€νν μμ
μ ꡬν
}
}
μμ κ°μ΄ Thread
ν΄λμ€λ₯Ό μμλ°μ μμ ν΄λμ€μμ run
λ©μλλ₯Ό μ€λ²λΌμ΄λ©νμ¬ μ€λ λμμ μ€νν μμ
μ ꡬνν©λλ€.
2. Runnable
μΈν°νμ΄μ€λ₯Ό ꡬννλ λ°©λ²:
public class MyRunnable implements Runnable {
public void run() {
// μ€λ λμμ μ€νν μμ
μ ꡬν
}
}
μμ κ°μ΄ Runnable
μΈν°νμ΄μ€λ₯Ό ꡬννλ ν΄λμ€μμ run
λ©μλλ₯Ό ꡬνν©λλ€.
μ€λ λ μμ
μ€λ λλ₯Ό μμνκΈ° μν΄μλ start
λ©μλλ₯Ό νΈμΆν΄μΌ ν©λλ€. start
λ©μλλ₯Ό νΈμΆνλ©΄, μ€λ λκ° λ
립μ μΌλ‘ μ€νλλ©° run
λ©μλμ μ½λκ° μ€νλ©λλ€.
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
μμ μμ μμ MyThread
ν΄λμ€λ Thread
ν΄λμ€λ₯Ό μμλ°μ μμ ν΄λμ€μ
λλ€. start
λ©μλλ₯Ό νΈμΆνμ¬ μ€λ λλ₯Ό μμν©λλ€.
μ€λ λ μ μ΄
μ€λ λλ₯Ό μ μ΄νκΈ° μν΄ λ€μκ³Ό κ°μ λ©μλλ₯Ό μ¬μ©ν μ μμ΅λλ€.
join()
: ν΄λΉ μ€λ λκ° μ’ λ£λ λκΉμ§ νΈμΆν μ€λ λλ₯Ό λΈλ‘ν©λλ€.yield()
: νμ¬ μ€ν μ€μΈ μ€λ λλ₯Ό μΌμμ μΌλ‘ λ©μΆκ³ λ€λ₯Έ μ€λ λμκ² μ€ν κΈ°νλ₯Ό μ보ν©λλ€.sleep(long millis)
: νμ¬ μ€ν μ€μΈ μ€λ λλ₯Ό μ§μ λ μκ° λμ λ©μΆ₯λλ€.interrupt()
: μ€λ λκ° λΈλ‘λμ΄ μλ μνμμ μΌμμ μΌλ‘ λ©μΆκ² νκ±°λ, μ€λ λλ₯Ό μ’ λ£μν€κΈ° μν΄ μ¬μ©λ©λλ€.
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
μμ μμ μμ join
λ©μλλ₯Ό μ¬μ©νμ¬ thread1
κ³Ό thread2
κ° μ’
λ£λ λκΉμ§ main
μ€λ λλ₯Ό λΈλ‘ν©λλ€. μ΄λ‘μ¨ thread1
κ³Ό thread2
κ° μ€νμ λ§μΉκ³ μ’
λ£λ νμ main
μ€λ λκ° κ³μ μ§νλ©λλ€.
μ€λ λ μ°μ μμ
μ€λ λμ μ°μ μμλ μ€νν λ CPU μμμ μ»μ νλ₯ μ κ²°μ νλλ° μ¬μ©λ©λλ€. μλ°μμλ μ€λ λμ μ°μ μμλ₯Ό 1μμ 10μ¬μ΄μ κ°μΌλ‘ μ€μ ν μ μμ΅λλ€. κΈ°λ³Έμ μΌλ‘ λͺ¨λ μ€λ λμ μ°μ μμλ 5λ‘ μ€μ λ©λλ€.
public class MyThread extends Thread {
public void run() {
System.out.println("Thread running...");
}
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.setPriority(Thread.MAX_PRIORITY);
thread2.setPriority(Thread.MIN_PRIORITY);
thread1.start();
thread2.start();
}
}
μμ μμ μμ thread1
μ μ°μ μμλ₯Ό μ΅κ³ μ°μ μμλ‘ μ€μ νκ³ , thread2
μ μ°μ μμλ₯Ό μ΅μ μ°μ μμλ‘ μ€μ νμμ΅λλ€. κ·Έλ¦¬κ³ λ μ€λ λλ₯Ό μμνλ©΄, thread1
μ thread2
λ³΄λ€ λ λ§μ CPU μμμ ν λΉλ°μ νλ₯ μ΄ λμμ§λλ€.
λκΈ°ν
μ¬λ¬ μ€λ λκ° κ³΅μ λ°μ΄ν°μ λμμ μ κ·Όνμ¬ μμ νλ κ²½μ°, μ€λ λ κ°μ λ°μ΄ν° μΌκ΄μ± λ¬Έμ κ° λ°μν μ μμ΅λλ€. μ΄λ₯Ό ν΄κ²°νκΈ° μν΄ μλ°μμλ λκΈ°ν(synchronization) κΈ°λ₯μ μ 곡ν©λλ€. λκΈ°νλ₯Ό μ¬μ©νμ¬ ν μ€λ λκ° κ³΅μ λ°μ΄ν°λ₯Ό μ¬μ©νλ λμ λ€λ₯Έ μ€λ λμ μ κ·Όμ μ νν μ μμ΅λλ€.
public class Counter {
private int count;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
μμ μμ μμ increment
λ©μλλ synchronized
ν€μλλ₯Ό μ¬μ©νμ¬ λκΈ°νλ λ©μλλ‘ μ μλμμ΅λλ€. μ΄λ‘μ¨ ν μ€λ λκ° increment
λ©μλλ₯Ό νΈμΆνμ¬ count
λ₯Ό μ¦κ°μν€λ λμ λ€λ₯Έ μ€λ λλ μ κ·Όμ μ ννκ² λ©λλ€.
μμ κ°μ λ°©λ²μΌλ‘ μλ°μμ μ€λ λλ₯Ό μμ±, μ μ΄νκ³ λκΈ°ννλ λ°©λ²μ μ¬μ©ν μ μμ΅λλ€. μ€λ λλ₯Ό μ¬μ©νμ¬ λ³λ ¬μ±μ νμ©ν λμλ λκΈ°ν λ¬Έμ μ λ°μ΄ν° μΌκ΄μ±μ κ³ λ €νμ¬ μ μ ν λ°©λ²μ μ ννμ¬ μ¬μ©ν΄μΌ ν©λλ€.
3. μ€λ λ μ‘°μ (Manipulating Threads)
μλ°μμλ μ€λ λλ₯Ό μ‘°μνμ¬ μ€λ λμ λμμ μ μ΄νκ³ λͺ¨λν°λ§ν μ μλ λ€μν κΈ°λ₯μ μ 곡ν©λλ€. μ΄λ₯Ό ν΅ν΄ μ€λ λμ μ€νμ μΌμ μ μ§, μ¬κ°, μ€μ§ λ±μ ν μ μμ΅λλ€.
μ€λ λ μΌμ μ μ§
μ€λ λλ₯Ό μΌμ μ μ§μν€λ λ°©λ²μΌλ‘λ sleep()
λ©μλμ yield()
λ©μλλ₯Ό μ¬μ©ν μ μμ΅λλ€.
sleep()
sleep()
λ©μλλ νμ¬ μ€ν μ€μΈ μ€λ λλ₯Ό μ§μ λ μκ° λμ λ©μΆλλ° μ¬μ©λ©λλ€. μ΄λ μ£Όμ΄μ§ μκ°μ΄ κ²½κ³Όνκ±°λ interrupt()
λ©μλκ° νΈμΆλλ©΄ λ€μ μ€νλκΈ° μμν©λλ€.
public class SleepThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SleepThread thread = new SleepThread();
thread.start();
}
}
μμ μμ μμ run()
λ©μλ λ΄λΆμμ Thread.sleep(1000)
μ νΈμΆνμ¬ μ€λ λλ₯Ό 1μ΄ λμ λ©μΆλλ‘ ν©λλ€. μ΄λ‘μ¨ μ€λ λκ° μ€νλλ©΄ 1λΆν° 5κΉμ§ μ«μλ₯Ό μΆλ ₯νκ³ , 1μ΄λ§λ€ μ«μκ° μΆλ ₯λκ² λ©λλ€.
yield()
yield()
λ©μλλ νμ¬ μ€ν μ€μΈ μ€λ λλ₯Ό μΌμμ μΌλ‘ λ©μΆκ³ λ€λ₯Έ μ€λ λμκ² μ€ν κΈ°νλ₯Ό μ보ν©λλ€. μ΄λ μ΄λ€ μ€λ λμκ² μ€ν κΈ°νλ₯Ό μ보ν μ§ μ νν κ²°μ ν μ μμ΅λλ€.
public class YieldThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread: " + i);
Thread.yield();
}
}
public static void main(String[] args) {
YieldThread thread = new YieldThread();
thread.start();
}
}
μμ μμ μμ run()
λ©μλ λ΄λΆμμ Thread.yield()
λ₯Ό νΈμΆνμ¬ μ€λ λλ₯Ό μΌμ μ μ§μν€λλ‘ ν©λλ€. μ΄λ‘μ¨ μ€λ λκ° μ€νλλ©΄ 1λΆν° 5κΉμ§ μ«μλ₯Ό μΆλ ₯νκ³ , κ° μ«μ μΆλ ₯ μ΄νμ μΌμμ μΌλ‘ λ©μΆκ³ λ€λ₯Έ μ€λ λμκ² μ€ν κΈ°νλ₯Ό μ보ν©λλ€.
μ€λ λ μ€μ§
μ€λ λλ₯Ό μ€μ§μν€λ λ°©λ²μΌλ‘λ stop()
λ©μλμ interrupt()
λ©μλλ₯Ό μ¬μ©ν μ μμ΅λλ€. νμ§λ§ stop()
λ©μλλ μ¬μ©μ κΆμ₯νμ§ μμΌλ©°, λμ interrupt()
λ©μλλ₯Ό μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
stop()
stop()
λ©μλλ μ€λ λλ₯Ό κ°μ λ‘ μ€μ§μν€λλ° μ¬μ©λ©λλ€. νμ§λ§ μ΄ λ©μλλ μ€λ λκ° μ€ν μ€μΈ μνμμ λ°λ‘ μ€μ§λκΈ° λλ¬Έμ, μ€λ λκ° μ 리νμ§ λͺ»ν μμ
μ΄λ λΈλ‘λ 리μμ€ λ±μ λ¨κΈΈ μ μμ΅λλ€. κ·Έλμ stop()
λ©μλλ μ¬μ©μ κΆμ₯νμ§ μμ΅λλ€.
interrupt()
interrupt()
λ©μλλ μ€λ λμ interrupted
μνλ₯Ό μ€μ νμ¬ μ€λ λκ° μ’
λ£λ μ μλλ‘ ν©λλ€. νΈμΆλ μ€λ λλ InterruptedException
μ λμ§ ν μ’
λ£ν μ μμ΅λλ€.
public class InterruptThread extends Thread {
public void run() {
try {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Thread Interrupted");
}
}
public static void main(String[] args) {
InterruptThread thread = new InterruptThread();
thread.start();
try {
Thread.sleep(3000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
μμ μμ μμ run()
λ©μλ λ΄λΆμμ Thread.sleep(1000)
μ νΈμΆνμ¬ μ€λ λλ₯Ό 1μ΄ λμ λ©μΆλλ‘ ν©λλ€. main
λ©μλμμλ 3μ΄ νμ thread
μ€λ λλ₯Ό interrupt()
λ©μλλ₯Ό νΈμΆνμ¬ μ€μ§μν€λλ‘ ν©λλ€. μ΄ν run
λ©μλμμ Thread.sleep(1000)
μ€ν μ€μ InterruptedException
μ΄ λ°μνλ©΄, μ€λ λκ° μ’
λ£λλλ‘ μ²λ¦¬ν©λλ€.
μ€λ λ μν
μ€λ λμ μνλ Thread
ν΄λμ€μ getState()
λ©μλλ₯Ό ν΅ν΄ μ μ μμ΅λλ€. μ€λ λ μνλ NEW
, RUNNABLE
, BLOCKED
, WAITING
, TIMED_WAITING
, TERMINATED
λ±μΌλ‘ μ μλλ©°, κ°κ°μ μνλ λ€μκ³Ό κ°μ μλ―Έλ₯Ό κ°μ§λλ€.
NEW
: μ€λ λκ° μμ§ μμλμ§ μμ μνλ₯Ό μλ―Έν©λλ€.RUNNABLE
: μ€λ λκ° μ€ν μ€μΈ μνλ₯Ό μλ―Έν©λλ€.BLOCKED
: μ€λ λκ° κ³΅μ 리μμ€λ₯Ό μ¬μ©νλ €κ³ νμ§λ§ λ€λ₯Έ μ€λ λμ μν΄ μ μ λμκΈ° λλ¬Έμ μ€νμ΄ λΆκ°λ₯ν μνλ₯Ό μλ―Έν©λλ€.WAITING
: μ€λ λκ° λ€λ₯Έ μ€λ λμμ ν΅μ§λ₯Ό κΈ°λ€λ¦¬λ©΄μ μ€νμ λ©μΆ μνλ₯Ό4. λ€μ€ μ€λ λ νκ²½μμμ λκΈ°ν (Synchronization)
λ€μ€ μ€λ λ νκ²½μμλ μ¬λ¬ μ€λ λκ° κ³΅μ λ°μ΄ν°μ λμμ μ κ·Όνμ¬ μμ νλ κ²½μ°κ° λ°μν μ μμ΅λλ€. μ΄λ¬ν μν©μμ μ€λ λ κ°μ λ°μ΄ν° μΌκ΄μ±μ μ μ§νκΈ° μν΄ μλ°μμλ λκΈ°ν(Synchronization) κΈ°λ₯μ μ 곡ν©λλ€. λκΈ°νλ ν μ€λ λκ° κ³΅μ λ°μ΄ν°λ₯Ό μ¬μ©νλ λμ λ€λ₯Έ μ€λ λμ μ κ·Όμ μ ννμ¬ λ°μ΄ν° μΌκ΄μ±μ 보μ₯νλ κΈ°λ²μ λλ€.
synchronized ν€μλ
μλ°μμ λκΈ°νλ₯Ό ꡬννλ κ°μ₯ κ°λ¨ν λ°©λ²μ synchronized
ν€μλλ₯Ό μ¬μ©νλ κ²μ
λλ€. synchronized
ν€μλλ₯Ό μ¬μ©νλ©΄ λ©μλ λλ λΈλ‘μ μκ³ μμ(critical section) μΌλ‘ μ§μ ν μ μμ΅λλ€. μκ³ μμμ ν λ²μ ν μ€λ λλ§ μ€νν μ μλ μμμ
λλ€.
λ©μλ λκΈ°ν
public class Counter {
private int count;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
μμ μμ μμ increment()
λ©μλμ getCount()
λ©μλλ synchronized
ν€μλλ₯Ό μ¬μ©νμ¬ λκΈ°νλ λ©μλλ‘ μ μλμμ΅λλ€. μ΄λ‘μ¨ ν μ€λ λκ° increment()
λλ getCount()
λ©μλλ₯Ό νΈμΆνμ¬ count
κ°μ λ³κ²½νκ±°λ μ½λ λμ λ€λ₯Έ μ€λ λλ μ κ·Όμ μ νλ°κ² λ©λλ€.
λΈλ‘ λκΈ°ν
public class Counter {
private int count;
public void increment() {
synchronized (this) {
count++;
}
}
public int getCount() {
synchronized (this) {
return count;
}
}
}
μμ μμ μμ increment()
λ©μλμ getCount()
λ©μλλ synchronized
λΈλ‘μΌλ‘ μ μλμμ΅λλ€. synchronized (this)
λ₯Ό μ¬μ©νμ¬ μκ³ μμμ μ§μ ν©λλ€. μ΄λ‘μ¨ ν μ€λ λκ° λΈλ‘ λ΄μ μ½λλ₯Ό μ€ννλ λμ λ€λ₯Έ μ€λ λλ μ κ·Όμ μ νλ°μ΅λλ€.
μ κΈ(Locks)κ³Ό 쑰건(Conditions)
μλ°μμλ Lock
μΈν°νμ΄μ€λ₯Ό μ¬μ©νμ¬ λ μ μ°ν λκΈ°νλ₯Ό μ 곡ν©λλ€. Lock
μΈν°νμ΄μ€λ₯Ό μ¬μ©νλ©΄ λ λ€μν μ κΈ λ° μ‘°κ±΄μ μ¬μ©νμ¬ μ€λ λ λκΈ°νλ₯Ό μ‘°μν μ μμ΅λλ€.
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private int count;
private Lock lock;
public Counter() {
count = 0;
lock = new ReentrantLock();
}
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
}
μμ μμ μμλ Lock
μΈν°νμ΄μ€λ₯Ό ꡬνν ReentrantLock
ν΄λμ€λ₯Ό μ¬μ©νμ¬ μ κΈ
5. μλ° μ€λ λ μμ
μ€λ λ μμ± μμ
public class MyThread extends Thread {
public void run() {
System.out.println("Hello from MyThread!");
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
μμ μμ λ MyThread
ν΄λμ€λ₯Ό μ μνκ³ run()
λ©μλλ₯Ό μ€λ²λΌμ΄λνμ¬ μ€λ λμ μ€ν λ‘μ§μ μμ±ν μμ μ
λλ€. main
λ©μλμμ MyThread
κ°μ²΄λ₯Ό μμ±νκ³ start()
λ©μλλ₯Ό νΈμΆνμ¬ μ€λ λλ₯Ό μ€νμν΅λλ€. start()
λ©μλλ₯Ό νΈμΆνλ©΄ μλ‘μ΄ μ€λ λκ° μμλκ³ , run()
λ©μλκ° μ€νλ©λλ€.
μ€λ λ λκΈ°ν μμ
public class Counter {
private int count;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
public class SynchronizedThread extends Thread {
private Counter counter;
public SynchronizedThread(Counter counter) {
this.counter = counter;
}
public void run() {
for (int i = 0; i < 5; i++) {
counter.increment();
}
}
public static void main(String[] args) {
Counter counter = new Counter();
SynchronizedThread thread1 = new SynchronizedThread(counter);
SynchronizedThread thread2 = new SynchronizedThread(counter);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count: " + counter.getCount());
}
}
μμ μμ λ λκΈ°νλ μΉ΄μ΄ν°λ₯Ό μ¬μ©νλ λ κ°μ μ€λ λλ₯Ό μμ±νλ μμ μ
λλ€. Counter
ν΄λμ€λ synchronized
ν€μλλ₯Ό μ¬μ©νμ¬ λκΈ°νλ λ©μλμΈ increment()
κ³Ό getCount()
λ₯Ό κ°μ§κ³ μμ΅λλ€. SynchronizedThread
ν΄λμ€λ Counter
κ°μ²΄λ₯Ό μμ±μλ‘ λ°μμ increment()
λ©μλλ₯Ό νΈμΆνμ¬ μΉ΄μ΄ν° κ°μ μ¦κ°μν΅λλ€.
main
λ©μλμμλ Counter
κ°μ²΄λ₯Ό μμ±νκ³ λ κ°μ SynchronizedThread
κ°μ²΄λ₯Ό μμ±νμ¬ μΉ΄μ΄ν°λ₯Ό μ¦κ°μν΅λλ€. μ€λ λ μ€νμ΄ λͺ¨λ λλ νμλ μΉ΄μ΄ν°μ μ΅μ’
κ°μ μΆλ ₯ν©λλ€.
μ€λ λ μΌμ μ μ§ μμ
public class SleepThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SleepThread thread = new SleepThread();
thread.start();
}
}
μμ μμ λ μΌμ ν κ°κ²©μΌλ‘ μ«μλ₯Ό μΆλ ₯νλ μ€λ λμ
λλ€. run()
λ©μλμμλ 1λΆν° 5κΉμ§μ μ«μλ₯Ό μΆλ ₯νκ³ , Thread.sleep(1000)
μ νΈμΆνμ¬ 1μ΄ λμ μ€λ λλ₯Ό μΌμ μ μ§μν΅λλ€. μ΄λ‘μ¨ κ° μ«μ μΆλ ₯ ν 1μ΄μ μΌμ μ μ§κ° λ°μνκ² λ©λλ€.
μ€λ λ μ€μ§ μμ
public class InterruptThread extends Thread {
public void run() {
try {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Thread Interrupted");
}
}
public static void main(String[] args) {
InterruptThread thread = new InterruptThread();
thread.start();
try {
Thread.sleep(3000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
μμ μμ λ interrupt()
λ©μλλ₯Ό μ¬μ©νμ¬ μ€λ λλ₯Ό μ€μ§μν€λ μμ μ
λλ€. run()
λ©μλμμλ 1λΆν° 5κΉμ§μ μ«μλ₯Ό μΆλ ₯νκ³ , Thread.sleep(1000)
μ νΈμΆνμ¬ 1μ΄ λμ μ€λ λλ₯Ό μΌμ μ μ§μν΅λλ€. main
λ©μλμμλ 3μ΄ νμ thread
μ€λ λλ₯Ό interrupt()
λ©μλλ₯Ό νΈμΆνμ¬ μ€μ§μν΅λλ€. μ΄ν run
λ©μλμμ Thread.sleep(1000)
μ€ν μ€μ InterruptedException
μ΄ λ°μνλ©΄, "Thread Interrupted"λΌλ λ©μμ§λ₯Ό μΆλ ₯ν©λλ€.
5. μλ° μ€λ λ μμ
μ€λ λ μμ± μμ
public class MyThread extends Thread {
public void run() {
System.out.println("Hello from MyThread!");
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
μμ μμ λ MyThread
ν΄λμ€λ₯Ό μ μνκ³ run()
λ©μλλ₯Ό μ€λ²λΌμ΄λνμ¬ μ€λ λμ μ€ν λ‘μ§μ μμ±ν μμ μ
λλ€. main
λ©μλμμ MyThread
κ°μ²΄λ₯Ό μμ±νκ³ start()
λ©μλλ₯Ό νΈμΆνμ¬ μ€λ λλ₯Ό μ€νμν΅λλ€. start()
λ©μλλ₯Ό νΈμΆνλ©΄ μλ‘μ΄ μ€λ λκ° μμλκ³ , run()
λ©μλκ° μ€νλ©λλ€.
μ΄ μμ μμλ MyThread
ν΄λμ€κ° Thread
ν΄λμ€λ₯Ό μμλ°μ μ€λ λλ‘ λμνλλ‘ κ΅¬νλμμ΅λλ€. Thread
ν΄λμ€μλ κΈ°λ³Έμ μΌλ‘ run()
λ©μλκ° μκ³ , μ΄ λ©μλλ₯Ό μ€λ²λΌμ΄λνμ¬ μ€λ λμ λμμ ꡬ체μ μΌλ‘ μ μν μ μμ΅λλ€.
μ€λ λ λκΈ°ν μμ
public class Counter {
private int count;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
public class SynchronizedThread extends Thread {
private Counter counter;
public SynchronizedThread(Counter counter) {
this.counter = counter;
}
public void run() {
for (int i = 0; i < 5; i++) {
counter.increment();
}
}
public static void main(String[] args) {
Counter counter = new Counter();
SynchronizedThread thread1 = new SynchronizedThread(counter);
SynchronizedThread thread2 = new SynchronizedThread(counter);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count: " + counter.getCount());
}
}
μμ μμ λ λκΈ°νλ μΉ΄μ΄ν°λ₯Ό μ¬μ©νλ λ κ°μ μ€λ λλ₯Ό μμ±νλ μμ μ
λλ€. Counter
ν΄λμ€μλ synchronized
ν€μλλ₯Ό μ¬μ©νμ¬ λκΈ°νλ λ©μλμΈ increment()
κ³Ό getCount()
λ₯Ό μμ±νμ΅λλ€. SynchronizedThread
ν΄λμ€λ Counter
κ°μ²΄λ₯Ό μμ±μλ‘ λ°μμ increment()
λ©μλλ₯Ό νΈμΆνμ¬ μΉ΄μ΄ν° κ°μ μ¦κ°μν΅λλ€.
main
λ©μλμμλ Counter
κ°μ²΄λ₯Ό μμ±νκ³ λ κ°μ SynchronizedThread
κ°μ²΄λ₯Ό μμ±νμ¬ μΉ΄μ΄ν°λ₯Ό μ¦κ°μν΅λλ€. μ€λ λμ μ€νμ΄ λͺ¨λ λλ νμλ μΉ΄μ΄ν°μ μ΅μ’
κ°μ μΆλ ₯ν©λλ€.synchronized
ν€μλλ‘ λ©μλλ₯Ό λκΈ°νν¨μΌλ‘μ¨ ν μ€λ λκ° ν΄λΉ λ©μλλ₯Ό μ€ννλ λμ λ€λ₯Έ μ€λ λμ μ κ·Όμ μ ννκ² λ©λλ€. μ΄λ₯Ό ν΅ν΄ 곡μ λ°μ΄ν°μ λν μ€λ λ κ°μ μΌκ΄μ±μ μ μ§ν μ μμ΅λλ€.
μ€λ λ μΌμ μ μ§ μμ
public class SleepThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SleepThread thread = new SleepThread();
thread.start();
}
}
μμ μμ λ sleep()
λ©μλλ₯Ό μ¬μ©νμ¬ μ€λ λλ₯Ό μΌμ μ μ§μν€λ μμ μ
λλ€. run()
λ©μλμμλ 1λΆν° 5κΉμ§μ μ«μλ₯Ό μΆλ ₯νκ³ , Thread.sleep(1000)
μ νΈμΆνμ¬ 1μ΄ λμ μ€λ λλ₯Ό μΌμ μ μ§μν΅λλ€. μ΄λ κ² νλ©΄ κ° μ«μ μΆλ ₯ ν 1μ΄μ© μΌμ μ μ§κ° λ°μνκ² λ©λλ€.
sleep()
λ©μλλ μ§μ λ μκ° λμ μ€λ λλ₯Ό μΌμ μ μ§μν€λ μν μ ν©λλ€. Thread.sleep(1000)
μ 1000λ°λ¦¬μ΄(1μ΄) λμ μ€λ λλ₯Ό μΌμ μ μ§μν¨ ν λ€μ μ½λλ₯Ό μ€νν©λλ€. InterruptedException
μ΄ λ°μν μ μμΌλ―λ‘ μμΈ μ²λ¦¬λ₯Ό ν΄μ£Όμ΄μΌ ν©λλ€.
μ€λ λ μ€μ§ μμ
public class InterruptThread extends Thread {
public void run() {
try {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Thread Interrupted");
}
}
public static void main(String[] args) {
InterruptThread thread = new InterruptThread();
thread.start();
try {
Thread.sleep(3000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
μμ μμ λ interrupt()
λ©μλλ₯Ό μ¬μ©νμ¬ μ€λ λλ₯Ό μ€μ§μν€λ μμ μ
λλ€. run()
λ©μλμμλ 1λΆν° 5κΉμ§μ μ«μλ₯Ό μΆλ ₯νκ³ , Thread.sleep(1000)
μ νΈμΆνμ¬ 1μ΄ λμ μ€λ λλ₯Ό μΌμ μ μ§μν΅λλ€. main
λ©μλμμλ 3μ΄ νμ thread
μ€λ λλ₯Ό interrupt()
λ©μλλ₯Ό νΈμΆνμ¬ μ€μ§μν΅λλ€.
interrupt()
λ©μλλ ν΄λΉ μ€λ λλ₯Ό μ€μ§μν€λ μν μ ν©λλ€. μμ μμλ thread.interrupt()
λ₯Ό νΈμΆνμ¬ thread
μ€λ λλ₯Ό μ€μ§μν΅λλ€. run
λ©μλμμ Thread.sleep(1000)
μ€ν μ€μ InterruptedException
μ΄ λ°μνλ©΄, catch λΈλ‘μ΄ μ€νλκ³ "Thread Interrupted"λΌλ λ©μμ§κ° μΆλ ₯λ©λλ€.
5. μλ° μ€λ λ μμ
μ€λ λ μμ± μμ
public class MyThread extends Thread {
public void run() {
System.out.println("Hello from MyThread!");
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
μ΄ μμ μμλ MyThread
ν΄λμ€λ₯Ό μ μνκ³ run()
λ©μλλ₯Ό μ€λ²λΌμ΄λ©νμ¬ μ€λ λμ μ€ν λ‘μ§μ μμ±νμ΅λλ€. main
λ©μλμμλ MyThread
κ°μ²΄λ₯Ό μμ±νκ³ start()
λ©μλλ₯Ό νΈμΆνμ¬ μ€λ λλ₯Ό μ€νμμΌ°μ΅λλ€. start()
λ©μλλ₯Ό νΈμΆνλ©΄ μλ‘μ΄ μ€λ λκ° μμλκ³ , ν΄λΉ μ€λ λμ run()
λ©μλκ° μ€νλ©λλ€.
μ΄ μμ μμ MyThread
ν΄λμ€λ Thread
ν΄λμ€λ₯Ό μμλ°μ μ€λ λλ‘ λμνλλ‘ κ΅¬νλμμ΅λλ€. Thread
ν΄λμ€λ κΈ°λ³Έμ μΌλ‘ run()
λ©μλλ₯Ό κ°μ§λ©°, μ΄ λ©μλλ₯Ό μ€λ²λΌμ΄λ©νμ¬ μ€λ λκ° λμν λ΄μ©μ ꡬ체μ μΌλ‘ μ μν μ μμ΅λλ€.
μ€λ λ λκΈ°ν μμ
public class Counter {
private int count;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
public class SynchronizedThread extends Thread {
private Counter counter;
public SynchronizedThread(Counter counter) {
this.counter = counter;
}
public void run() {
for (int i = 0; i < 5; i++) {
counter.increment();
}
}
public static void main(String[] args) {
Counter counter = new Counter();
SynchronizedThread thread1 = new SynchronizedThread(counter);
SynchronizedThread thread2 = new SynchronizedThread(counter);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count: " + counter.getCount());
}
}
μμ μμ λ λκΈ°νλ μΉ΄μ΄ν°λ₯Ό μ¬μ©νλ λ κ°μ μ€λ λλ₯Ό μμ±νλ μμ μ
λλ€. Counter
ν΄λμ€λ synchronized
ν€μλλ₯Ό μ¬μ©νμ¬ λκΈ°νλ increment()
κ³Ό getCount()
λ©μλλ₯Ό κ°μ§κ³ μμ΅λλ€. SynchronizedThread
ν΄λμ€λ Counter
κ°μ²΄λ₯Ό μμ±μλ‘ λ°μμ increment()
λ©μλλ₯Ό νΈμΆνμ¬ μΉ΄μ΄ν° κ°μ μ¦κ°μν΅λλ€.
main
λ©μλμμλ Counter
κ°μ²΄λ₯Ό μμ±νκ³ λ κ°μ SynchronizedThread
κ°μ²΄λ₯Ό μμ±νμ¬ μΉ΄μ΄ν°λ₯Ό μ¦κ°μν΅λλ€. μ€λ λμ μ€νμ΄ λͺ¨λ λλ νμλ μΉ΄μ΄ν°μ μ΅μ’
κ°μ μΆλ ₯ν©λλ€. synchronized
ν€μλλ₯Ό μ¬μ©νμ¬ λ©μλλ₯Ό λκΈ°ννλ©΄ ν μ€λ λκ° ν΄λΉ λ©μλλ₯Ό μ€ννλ λμ λ€λ₯Έ μ€λ λμ μ κ·Όμ μ νν μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ 곡μ λ°μ΄ν°μ λν μ€λ λ κ°μ μΌκ΄μ±μ μ μ§ν μ μμ΅λλ€.
μ€λ λ μΌμ μ μ§ μμ
public class SleepThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SleepThread thread = new SleepThread();
thread.start();
}
}
μμ μμ λ sleep()
λ©μλλ₯Ό μ¬μ©νμ¬ μ€λ λλ₯Ό μΌμ μ μ§μν€λ μμ μ
λλ€. run()
λ©μλμμλ 1λΆν° 5κΉμ§μ μ«μλ₯Ό μΆλ ₯νκ³ , Thread.sleep(1000)
μ νΈμΆνμ¬ 1μ΄ λμ μ€λ λλ₯Ό μΌμ μ μ§μν΅λλ€. μ΄λ κ² νλ©΄ κ° μ«μ μΆλ ₯ ν 1μ΄μ© μΌμ μ μ§κ° λ°μνκ² λ©λλ€.
sleep()
λ©μλλ μ§μ λ μκ° λμ μ€λ λλ₯Ό μΌμ μ μ§μν€λ μν μ ν©λλ€. Thread.sleep(1000)
μ 1000λ°λ¦¬μ΄(1μ΄) λμ μ€λ λλ₯Ό μΌμ μ μ§μν¨ ν λ€μ μ½λλ₯Ό μ€νν©λλ€. InterruptedException
μ΄ λ°μν μ μμΌλ―λ‘ μμΈ μ²λ¦¬λ₯Ό ν΄μ£Όμ΄μΌ ν©λλ€.
μ€λ λ μ€μ§ μμ
public class InterruptThread extends Thread {
public void run() {
try {
for (int i = 1; i
λκΈ