μ€λ λ(Thread)λ νλμ νλ‘κ·Έλ¨μμ μ€νλλ λ
립μ μΈ μ€ν νλ¦(μμ
λ¨μ)μ΄λ€.
μλ°μμ μ€λ λλ₯Ό μ¬μ©νλ©΄ μ¬λ¬ μμ
μ λμμ μ€ν(λ³λ ¬ μ²λ¦¬, λ©ν°νμ€νΉ) ν μ μλ€.
Thread
ν΄λμ€λ₯Ό μμνλ λ°©λ²class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " μ€ν μ€: " + i);
try {
Thread.sleep(500); // 0.5μ΄ λκΈ°
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThreadExample {
public static void main(String[] args) {
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.start(); // μ€λ λ μμ
t2.start();
}
}
π
start()
λ₯Ό νΈμΆνλ©΄ μλ‘μ΄ μ€λ λκ° μμ±λλ©°run()
μ΄ μ€νλ¨
πThread.sleep(500)
μ μ¬μ©νλ©΄ 0.5μ΄ λμ μ€λ λκ° λ©μΆ€
Runnable
μΈν°νμ΄μ€λ₯Ό ꡬννλ λ°©λ²class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " μ€ν μ€: " + i);
}
}
}
public class RunnableExample {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
t1.start();
t2.start();
}
}
π
Runnable
μ μ¬μ©νλ©΄Thread
λ₯Ό μμλ°μ§ μμλ μ€λ λλ₯Ό μ€νν μ μμ
πThread
λ₯Ό μμνλ λ°©λ²λ³΄λ€ λ μ μ°νκ² νμ© κ°λ₯ (λ€μ€ μμ λ¬Έμ ν΄κ²°)
public class LambdaThreadExample {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " μ€ν μ€: " + i);
}
});
t1.start();
}
}
π
Runnable
μ λλ€μμΌλ‘ κ°λ¨νκ² νν κ°λ₯
π μ½λκ° κ°κ²°ν΄μ§κ³ κ°λ μ±μ΄ μ’μμ§
λ©μλ | μ€λͺ |
---|---|
start() | μλ‘μ΄ μ€λ λλ₯Ό μμ |
run() | μ€λ λκ° μ€νν μ½λ |
sleep(ms) | μ§μ λ μκ°(ms) λμ νμ¬ μ€λ λλ₯Ό λ©μΆ€ |
join() | λ€λ₯Έ μ€λ λκ° μ’ λ£λ λκΉμ§ νμ¬ μ€λ λκ° κΈ°λ€λ¦Ό |
isAlive() | μ€λ λκ° μ€ν μ€μΈμ§ νμΈ |
setPriority(int) | μ€λ λμ μ°μ μμλ₯Ό μ€μ |
sleep()
μμ class SleepThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " μ€ν μ€: " + i);
try {
Thread.sleep(1000); // 1μ΄ λμ λ©μΆ€
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
join()
μμ (μ€λ λ μ’
λ£ λκΈ°)public class JoinExample {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println("T1 μ€ν μ€: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
try {
t1.join(); // t1μ΄ μ’
λ£λ λκΉμ§ κΈ°λ€λ¦Ό
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("λ©μΈ μ€λ λ μ’
λ£");
}
}
π
join()
μ μ¬μ©νλ©΄t1
μ΄ λλ λκΉμ§main
μ€λ λκ° κΈ°λ€λ¦Ό
πjoin()
μ΄ μμΌλ©΄main
μ€λ λκ° λ¨Όμ μ’ λ£λ μλ μμ
λ©ν°μ€λ λ νκ²½μμλ μ¬λ¬ κ°μ μ€λ λκ° λμμ 곡μ μμ(λ³μ, νμΌ, λ°μ΄ν°λ² μ΄μ€)μ μ κ·Όν μ μλ€.
μ΄λ κ²½μ μν(Race Condition)κ° λ°μν μ μμΌλ©°, μ΄λ₯Ό λ°©μ§νκΈ° μν΄ λκΈ°ν(Synchronization)λ₯Ό μ¬μ©νλ€.
synchronized
)λ₯Ό μ¬μ©ν μμ class Counter {
private int count = 0;
// λκΈ°νλ λ©μλ (ν λ²μ νλμ μ€λ λλ§ μ κ·Ό κ°λ₯)
public synchronized void increment() {
count++;
System.out.println(Thread.currentThread().getName() + " - Count: " + count);
}
}
public class SynchronizedExample {
public static void main(String[] args) {
Counter counter = new Counter();
Runnable task = () -> {
for (int i = 0; i < 5; i++) {
counter.increment();
}
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
}
}
π
synchronized
ν€μλλ₯Ό μ¬μ©νλ©΄ ν λ²μ νλμ μ€λ λλ§increment()
λ₯Ό μ€ν
πRace Condition
μ λ°©μ§νμ¬ λ°μ΄ν° μΌκ΄μ±μ μ μ§
β
μ€λ λ(Thread)λ νλμ νλ‘κ·Έλ¨ λ΄μμ μ€νλλ λ
립μ μΈ νλ¦
β
λ©ν°μ€λ λλ₯Ό μ¬μ©νλ©΄ μ¬λ¬ μμ
μ λμμ μν κ°λ₯
β
Thread
λ₯Ό μμλ°κ±°λ, Runnable
μ ꡬννμ¬ μ€λ λ μμ± κ°λ₯
β
start()
λ₯Ό νΈμΆνλ©΄ μλ‘μ΄ μ€λ λκ° μ€νλ¨
β
sleep()
, join()
, synchronized
λ±μ νμ©νμ¬ μ€λ λ μ μ΄ κ°λ₯
β
λ©ν°μ€λ λ νκ²½μμλ λκΈ°ν(synchronized
)λ₯Ό μ¬μ©νμ¬ λ°μ΄ν° μΆ©λ λ°©μ§