์๋ฐ(Java) - Thread(๋ฉํฐ ์ค๋ ๋)
๋ฉํฐ ์ค๋ ๋(Multi Thread)?
- ํ๋์ ํ๋ก๊ทธ๋จ์์ ์ฌ๋ฌ๊ฐ์ง ์ผ์ ๋์์ ์ํํ๋ ๊ฒ
When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon. |
Main Thread
๐ก๋ชจ๋ ์๋ฐ ์ดํ๋ฆฌ์ผ์ด์ ์ Main Thread๊ฐ main() ๋ฉ์๋๋ฅผ ์คํํ๋ฉด์ ์์๋ฉ๋๋ค.
๐ก์ค๋ ๋๋ ์ด์์ฒด์ ๊ฐ ์คํ์ํค๊ธฐ ๋๋ฌธ์ ์ฝ๊ฐ์ ํ ์ด ์์
์ฑ๊ธ ์ค๋ ๋๋ ๋ฉ์ธ ์ค๋ ๋๊ฐ ์ข ๋ฃ๋๋ฉด ํ๋ก์ธ์ค๋ ์ข ๋ฃ๋์ง๋ง,
๋ฉํฐ ์ค๋ ๋๋ ๋ฉ์ธ ์ค๋ ๋๊ฐ ์ข ๋ฃ๋๋๋ผ๋ ์คํ ์ค์ธ ์ค๋ ๋๊ฐ ํ๋๋ผ๋ ์๋ค๋ฉด ํ๋ก์ธ์ค๋ ์ข ๋ฃ๋์ง ์์ต๋๋ค.
Thread ์์ฑ
There are two ways to create a new thread of execution. One is to declare a class to be a subclass of Thread. ๐กThis subclass should override the run method of class Thread. An instance of the subclass can then be allocated and started.
Thread ํด๋์ค ์์
๐จ์ ์ผ ์ฌ์ด ๋ฐฉ๋ฒ์ด์ง๋ง ์ข์ ๋ฐฉ๋ฒ์ ์๋. ๋ค๋ฅธ ํด๋์ค ์์์ ๋ชป ๋ฐ์
public class Main {
public static void main(String[] args) {
Thread test = new TestThread();
test.start();
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
System.out.println("์ฌ๊ธฐ๋ ๋ฉ์ธ ์ค๋ ๋ ์
๋๋ค." + sum);
}
System.out.println(Thread.currentThread() + "ํฉ๊ณ : " + sum);
}
}
class TestThread extends Thread {
@Override
public void run() {
int sum = 0;
for(int i = 0; i <= 100; i++) {
sum += i;
System.out.println("์ฌ๊ธฐ๋ ํ
์คํธ ์ค๋ ๋ ์
๋๋ค. : " + sum);
}
System.out.println(Thread.currentThread() + "ํฉ๊ณ : " + sum);
}
}
Runnable ์ธํฐํ์ด์ค ๊ตฌํ
- new๋ฅผ ํตํด Thread ํด๋์ค ๊ฐ์ฒด๋ฅผ ์์ฑ ํ start() ๋ฉ์๋๋ฅผ ํตํด ๋ค๋ฅธ ์ค๋ ๋์์ ํ ์์ ์ ํ ๋นํ๋ ๋ฐฉ๋ฒ
- Thread ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋๋ Runnable ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ํด๋์ค ๊ฐ์ฒด๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ต๋๋ค.
- start() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์์ ์ค๋ ๋๋ ์์ ์ run() ๋ฉ์๋๋ฅผ ์คํ ํฉ๋๋ค.
import static java.lang.Thread.sleep;
public class RunThread implements Runnable {
@Override
public void run() {
int sum = 0;
for(int i = 0; i < 5; i++) {
sum += i;
try {
sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("" + Thread.currentThread() + sum);
}
System.out.println(Thread.currentThread() + " ํฉ๊ณ : " + sum);
}
}
public class Main {
public static void main(String[] args) {
Runnable runTh = new RunThread();
Thread th1 = new Thread(runTh);
runTh1.start();
Runnable runTh2 = new RunThread();
Thread th2 = new Thread(runTh2);
runTh2.start();
}
}
Runnabe runTh = new RunThread();
์ํํด์ผ ํ ์์ ๋ด์ฉ์ ํฌํจํ๊ณ ์์ง๋ง ์ค์ ์ค๋ ๋๋ ์๋๊ธฐ ๋๋ฌธ์ Thread ๊ฐ์ฒด๋ฅผ ์์ฑ์ Runnable ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ๋ฃ์ด์ค ํ start() ํด์ผ ํ๋ค.
Thread[Thread-0,5,main]0
Thread[Thread-1,5,main]0
Thread[Thread-0,5,main]1
Thread[Thread-1,5,main]1
Thread[Thread-1,5,main]3
Thread[Thread-0,5,main]3
Thread[Thread-0,5,main]6
Thread[Thread-1,5,main]6
Thread[Thread-1,5,main]10
Thread[Thread-0,5,main]10
Thread[Thread-1,5,main] ํฉ๊ณ : 10
Thread[Thread-0,5,main] ํฉ๊ณ : 10
์ต๋ช ์ ๊ฐ์ฒด ์์ฑ (์ผํ์ฉ)
Runnable task = new Runnable() {
@Override
public void run() {
int sum = 0;
for(int i = 0 ; i < 10; i++) {
sum += i;
System.out.println("" + Thread.currentThread() + sum);
}
System.out.println(Thread.currentThread() + " ํฉ๊ณ : " + sum);
}
}; // ๊ตฌํ๋ถ์ ๋์ด๋ค ์๋ฏธ๋ก ';' ๋ถ์ฌ์ผ ํจ.
Thread runTh3 = new Thread(task);
runTh3.start();
์ต๋ช ์ ๊ฐ์ฒด๋ฅผ ๋๋ค์์ผ๋ก ์์ฑ
Runnable task2 = () -> {
int sum = 0;
for(int i = 0 ; i < 10; i++) {
sum += i;
System.out.println("" + Thread.currentThread() + sum);
}
System.out.println(Thread.currentThread() + " ํฉ๊ณ : " + sum);
};
Thread runTh4 = new Thread(task2);
runTh4.start();
System.out.println("๋๋ main ์
๋๋ค.");
Thread ์ฐ์ ์์
์ฐ์ ์์(Priority) ๋ฐฉ์
์ฐ์ ์์๊ฐ ๋์ ์ค๋ ๋๊ฐ ์คํ์ ๋ ๋ง์ด ํ๋๋ก ์ค์ผ์ค๋ง ํ๋ ๋ฐฉ๋ฒ
thread.setPriority(1)
: ์ฐ์ ์์ ๊ฐ์ฅ ๋ฎ์thread.setPriority(10)
: ์ฐ์ ์์ ๊ฐ์ฅ ๋์
์ํ ํ ๋น ๋ฐฉ์
- ์๊ฐ ํ ๋น๋์ ์ ํด์ ํ๋์ ์ค๋ ๋๋ฅผ ์ ํด์ง ์๊ฐ๋งํผ๋ง ์คํํ๋ ๋ฐฉ๋ฒ
- ํด๋น ๋ฐฉ์์ JVM ์์์ ์ด๋ฃจ์ด์ง๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๊ฐ ์ ์ดํ ์ ์์.
Thread ์ํ
์ค๋ ๋๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฉด ์ฐ์ ์คํ ๋๊ธฐ ์ํ๋ก ๋ค์ด๊ฐ๋๋ค.
์คํ๋๊ธฐ ์ํ๋ ์ฝ์ด์์ ์์ ์ ํ ๋น๋ฐ์ง ๋ชปํ ์ํ ์ ๋๋ค.
์คํ ๋๊ธฐ ์ํ์ ์๋ ์ค๋ ๋ ์ค ์ค๋ ๋ ์ค์ผ์ค๋ง์ผ๋ก ์ ํ๋ ์ค๋ ๋๊ฐ CPU๋ฅผ ์ ์ ํ๊ณ ์ด์์ฒด์ ๊ฐ run()์ ์คํ ํฉ๋๋ค.
์ด ๋ CPU๋ฅผ ์ ์ ํ๊ณ ์๋ ์ํ๊ฐ ์คํ ์ํ ์ ๋๋ค.
run() ๋ฉ์๋๊ฐ ๋๋์ง ์์๋ ์ค๋ ๋ ์ค์ผ์ค๋ง์ ์ํด ๋ค์ ์คํ ๋๊ธฐ ์ํ๋ก ๋์๊ฐ๋ฉฐ ๋ฒ๊ฐ์ ๊ฐ๋ฉด์ ๋ด์ฉ์ ๋๋ผ ๋๊น์ง ์ง์ํฉ๋๋ค.
๊ฒฝ์ฐ์ ๋ฐ๋ผ run() ๋ฉ์๋๊ฐ ์คํ์ค์ธ ์ค๋ ๋๋ฅผ ์ผ์ ์ ์ง ์ํฌ ์๋ ์๋๋ฐ ์ผ์ ์ ์ง ํ์๋ ๋ค์ ์คํ ๋๊ธฐ ์ํ๋ก ๊ฐ๋๋ค.
Thread ์ํ ์ ์ด
- ์คํ ์ค์ธ ์ค๋ ๋ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ ์ค๋ ๋ ์ํ ์ ์ด๋ผ๊ณ ํฉ๋๋ค.
- ๋ฉํฐ ํ๋ก๊ทธ๋จ์ ๋ง๋ค๊ธฐ ์ํด์๋ ์ ๊ตํ ์ค๋ ๋ ์ํ ์ ์ด๊ฐ ํ์ํฉ๋๋ค.
๋ฉ์๋ | ์ค๋ช |
interrupt() | ์ผ์ ์ ์ง ์ํ์ ์ค๋ ๋์์ interruptException ์์ธ๋ฅผ ๋ฐ์์์ผ, ์์ธ ์ฒ๋ฆฌ ์ฝ๋ |
notify(), notifyAll() | ๋๊ธฐํ ๋ธ๋ก ๋ด์์ wait() ๋ฉ์๋์ ์ํด ์ผ์ ์ ์ง ์ํ์ ์๋ ์ค๋ ๋๋ฅผ ์คํ ๋๊ธฐ ์ํ๋ก ๋ง๋ฌ |
sleep() | ์ฃผ์ด์ง ์๊ฐ ๋์ ์ค๋ ๋๋ฅผ ์ผ์ ์ ์ง ์ํ๋ก ๋ง๋ฌ |
join() | join() ๋ฉ์๋๋ฅผ ํธ์ถํ ์ค๋ ๋๋ ์ผ์ ์ ์ง ์ํ๊ฐ ๋๋ค. ์คํ ๋๊ธฐ ์ํ๋ก ๊ฐ๋ ค๋ฉด join() ๋ฉ์๋๋ฅผ ๋ฉค๋ฒ๋ก ๊ฐ์ง ์ค๋ ๋๊ฐ ์ข ๋ฃ ๋๊ฑฐ๋, ๋งค๊ฐ๊ฐ์ผ๋ก ์ฃผ์ด์ง ์๊ฐ์ด ์ง๋์ผ ํจ |
wait() | ๋๊ธฐํ ๋ธ๋ก ๋ด์์ ์ค๋ ๋๋ฅผ ์ผ์ ์ ์ง ์ํ๋ก ๋ง๋ฌ * ๋งค๊ฐ๋ณ์๊ฐ ์ฃผ์ด์ง๋ฉด ์ฃผ์ด์ง ์๊ฐ์ด ์ง๋๋ฉด ์๋์ผ๋ก ์คํ ๋๊ธฐ ์ํ๊ฐ ๋จ. * ์๊ฐ์ด ์ฃผ์ด์ง์ง ์์ผ๋ฉด notify(), notifyAll() ๋ฉ์๋์ ์ํด ์คํ ๋๊ธฐ ์ํ๋ก ์ ํ |
์ฃผ์ด์ง ์๊ฐ ๋์ ์ผ์ ์ ์ง(sleep())
- ์คํ์ค์ธ ์ค๋ ๋๋ฅผ ์ผ์ ์๊ฐ๋์ ๋๊ธฐ ์ํ๋ก ๋ง๋ฌ
- ๋ฐ๋ณต ์ํ์ ๋ํ ์๊ฐ์ ๋ฆ์ถ ๋ ์ฌ์ฉํ๊ฑฐ๋, ์ธํฐ๋ฝํธ ์์ธ์ฒ๋ฆฌ๋ฅผ ์ํด์ ์ฌ์ฉ
import java.awt.*;
import static java.lang.Thread.sleep;
public class Main {
public static void main(String[] args) {
Toolkit toolkit = Toolkit.getDefaultToolkit();
for(int i = 0; i < 10; i++) {
toolkit.beep();
try {
sleep(3000);
} catch (InterruptedException e) {
}
}
}
}
3์ด ์ฃผ๊ธฐ๋ก 10๋ฒ ๋นํ์ ๋ฐ์ํ๋ ์ฝ๋
๋ค๋ฅธ ์ค๋ ๋์ ์ข ๋ฃ๋ฅผ ๊ธฐ๋ค๋ฆผ(join())
- ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์ข
๋ฃ๋ ๋ ๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ์คํํด์ผ ํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉ
์) ์๋ฅผ ๋ค์ด ๊ณ์ฐ ์์ ์ ํ๋ ์ค๋ ๋๊ฐ ๋ชจ๋ ๊ณ์ฐ์ ๋ง์น๊ณ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐ์ ์ด์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ
๐ถ join() ์ฌ์ฉ ์
public class Main {
public static void main(String[] args) {
SumTh sumTh = new SumTh();
sumTh.start();
System.out.println("ํฉ : " + sumTh.getSum());
}
}
class SumTh extends Thread {
private long sum;
public long getSum() {
return sum;
}
public void setSum(long sum) {
this.sum = sum;
}
@Override
public void run() {
for(int i = 0; i < 100; i++) {
sum += 1;
try {
sleep(1);
} catch (InterruptedException e) {}
}
}
}
ํฉ : 0
Thread๊ฐ ์คํ ๋๊ธฐ ๊น์ง ์๊ฐ๋ณด๋ค main์์ getSum() ์คํํ๋ ์๊ฐ์ด ํจ์ฌ ๋น ๋ฅด๊ธฐ ๋๋ฌธ์ for๋ฌธ ๋๊ธฐ ์ ์ ๋๋์ 0์ผ๋ก ๋์ด.
๐ก join()์ ๋ฌดํ๋๊ธฐ(์ธ์์ ์๋ฌด๊ฒ๋ ์ ์) ๊ฑธ๊ฑฐ๋ ์๊ฐ์ ์ง์ ํ ์๋ ์์. ์) join(200), join() …
๐ถ join() ์ฌ์ฉ ํ
public class Main {
public static void main(String[] args) {
SumTh sumTh = new SumTh();
sumTh.start();
try {
sumTh.join(); // sumTh๊ฐ ์ข
๋ฃ ๋ ๋ ๊น์ง main์ด ๋๊ธฐ ํ๊ณ ์์
} catch (InterruptedException e) {}
System.out.println("ํฉ : " + sumTh.getSum());
}
}
class SumTh extends Thread {
private long sum;
public long getSum() {
return sum;
}
public void setSum(long sum) {
this.sum = sum;
}
@Override
public void run() {
for(int i = 0; i < 100; i++) {
sum += 1;
try {
sleep(1);
} catch (InterruptedException e) {}
}
}
}
ํฉ : 100
์ค๋ ๋ ๊ฐ ํ์ (wait(), notify(), nofifyAll())
- ๊ฒฝ์ฐ์ ๋ฐ๋ผ ๋ ๊ฐ์ ์ค๋ ๋๊ฐ ๋ฒ๊ฐ์๊ฐ๋ฉฐ ์คํํด์ผ ํ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
- ํ ์ค๋ ๋๊ฐ ์์ ์ ์๋ฃํ๋ฉด notify() ๋ฉ์๋๋ฅผ ํธ์ถํด์ ์ผ์ ์ ์ง ์ํ์ ์๋ ๋ค๋ฅธ ์ค๋ ๋๋ฅผ ์คํ ๋๊ธฐ ์ํ๋ก ๋ง๋ค๊ณ , ์์ ์ ๋๋ฒ์งธ ์์ ์ ํ์ง ์๋๋ก wait() ๋ฉ์๋๋ฅผ ํธ์ถ ํฉ๋๋ค.
- notifyAll() ๋ฉ์๋๋ wait()์ ์ํด ์ผ์ ์ ์ง๋ ๋ชจ๋ ์ค๋ ๋๋ฅผ ์คํ ๋๊ธฐ ์ํ๋ก ๋ง๋ญ๋๋ค.
Main
public class Main {
public static void main(String[] args) {
WorkObject sharedObject = new WorkObject();
ThreadA thA = new ThreadA(sharedObject);
ThreadB thB = new ThreadB(sharedObject);
thA.start();
thB.start();
}
}
WorkObject
public class WorkObject {
public synchronized void methodA() {
System.out.println("Thread์ methodA() ์์
์คํ");
notify(); // ์ผ์์ ์ง ์ํ์ธ ThreadB๋ฅผ ์คํ ๋๊ธฐ ์ํ๋ก ์ ํ
try {
wait(); // ThreadA๋ฅผ ์ผ์ ์ ์ง ์ํ๋ก ๋ง๋ฌ
} catch(InterruptedException e) {}
}
public synchronized void methodB() {
System.out.println("Thread์ methodB() ์์
์คํ");
notify(); // ์ผ์์ ์ง ์ํ์ธ ThreadA๋ฅผ ์คํ ๋๊ธฐ ์ํ๋ก ์ ํ
try {
wait(); // ThreadB๋ฅผ ์ผ์ ์ ์ง ์ํ๋ก ๋ง๋ฌ
} catch(InterruptedException e) {}
}
}
์ค๋ ๋์์ ๊ณตํต์ผ๋ก ์ฌ์ฉํ๋ ํด๋์ค ์์ฑ
synchronized : ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ๋์ ์ ์์ด ํ์ฉ์ด ๋์ง ์๋๋ก lock์ ๊ฑฐ๋ ์์
ThreadA
public class ThreadA extends Thread {
private WorkObject workObject;
public ThreadA(WorkObject workObject) {
this.workObject = workObject;
}
@Override
public void run() {
for(int i = 0; i < 10; i++) {
workObject.methodA();
}
}
}
ThreadB
public class ThreadB extends Thread {
private WorkObject workObject;
public ThreadB(WorkObject workObject) {
this.workObject = workObject;
}
@Override
public void run() {
for(int i = 0; i < 10; i++) {
workObject.methodB();
}
}
}
์ค๋ ๋์ ์์ ํ ์ข ๋ฃ (stop ํ๋๊ทธ, interrupt())
- ์ค๋ ๋์ ์์ ํ ์ข ๋ฃ ๋ฐฉ๋ฒ์ stop ํ๋๊ทธ๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ๊ณผ interrupt() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
๐ถ stop ํ๋๊ทธ๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ
Main
public class Main {
public static void main(String[]args) throws InterruptedException {
RunThread runThread = new RunThread();
runThread.start();
Thread.sleep(1000);
runThread.setStop(true);
}
}
RunThread
public class RunThread extends Thread {
private boolean stop; // stop ํ๋๊ทธ ์ค์
public void setStop(boolean stop) {
this.stop = stop;
}
public void run() {
while(!stop) {
System.out.println("Thread ์คํ ์ค...");
}
System.out.println("์์ ์ ๋ฆฌ");
System.out.println("์คํ ์ข
๋ฃ");
}
}
๐ถ interrupt() ๋ฉ์๋๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ
- interrupt() ๋ฉ์๋๋ ์ค๋ ๋๊ฐ ์ผ์ ์ ์ง ์ํ์ ์์ ๋ InterruptException ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค.
- ์ด๊ฒ์ ์ด์ฉํ์ฌ run() ๋ฉ์๋๋ฅผ ์ ์ ์ข ๋ฃ ์ํฌ ์ ์๋ค.
public class Main {
public static void main(String[]args) {
InterruptThread interThread = new InterruptThread();
interThread.start();
try {
Thread.sleep(1000);
} catch(InterruptedException e) { }
interThread.interrupt();
}
}
public class InterruptThread extends Thread {
@Override
public void run() {
try {
while (true) {
System.out.println("์ค๋ ๋ ์คํ ์ค.....");
sleep(1); // interrupt ๊ฑธ๋ฆด ์ ์๋ ํ์ด๋ฐ (while(true) ํ์ถ ์กฐ๊ฑด)
}
} catch(InterruptedException e) {
System.out.println("์ธํฐ๋ฝํธ ๋ฐ์......");
}
System.out.println("์ข
๋ฃ๋ฅผ ์ํด ์์ ์ ๋ฆฌ ์ค.....");
System.out.println("์คํ ์ข
๋ฃ");
}
}
๋๊ธฐํ (synchronized)
- ๋ฉํฐ ์ค๋ ๋์์ ํน์ ๋ฉ์๋๋ ๋ธ๋ก{}์ ๋ํด lock(์ ๊ธ)์ ์ค์ ํ๋ ๊ฒ
- ๋์ ์ ๊ทผ์ผ๋ก ์ธํด ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ฉฐ, ์ฌ์ฉ์ ๊ธ๊ฒฉํ ์ฑ๋ฅ ์ ํ๊ฐ ๋ฐ์ํ ์ ์์
โก๏ธ ์ ์ฌ ์ ์์ ์ ์ฌ์ฉํด์ผ ํจ
๐ถ synchronized ํ๊ธฐ ์ ..
import static java.lang.Thread.sleep;
public class Main {
public static void main(String[] args) {
SharedValue sharedValue = new SharedValue();
// Runnable ์ธํฐํ์ด์ค ์ต๋ช
์ ์ค๋ ๋ ์์ฑ
Runnable th1 = new Runnable() {
@Override
public void run() {
sharedValue.setValue(100);
}
};
Thread thread1 = new Thread(th1);
thread1.setName("์ค๋ ๋ 1"); // ์ค๋ ๋ ์ด๋ฆ์ ์ค์
thread1.start();
// Runnable ์ธํฐํ์ด์ค ๋๋ค์์ผ๋ก ์ต๋ช
์ ์ค๋ ๋ ์์ฑ
Runnable th2 = () -> {
sharedValue.setValue(200);
};
Thread thread2 = new Thread(th2);
thread2.setName("์ค๋ ๋ 2");
thread2.start();
}
}
class SharedValue {
private int value = 0;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
try {
sleep(2000);
} catch(InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + "์ ๊ฐ : " + getValue());
}
}
์ค๋ ๋ 1์ ๊ฐ : 200
์ค๋ ๋ 2์ ๊ฐ : 200
synchronized ์ํ๋ฉด ๊ฐ์ด ๊นจ์ง.
public void setValue(int value) {}
๐ถ synchronized ์ ์ฉ ํ
import static java.lang.Thread.sleep;
public class Main {
public static void main(String[] args) {
SharedValue sharedValue = new SharedValue();
// Runnable ์ธํฐํ์ด์ค ์ต๋ช
์ ์ค๋ ๋ ์์ฑ
Runnable th1 = new Runnable() {
@Override
public void run() {
sharedValue.setValue(100);
}
};
Thread thread1 = new Thread(th1);
thread1.setName("์ค๋ ๋ 1"); // ์ค๋ ๋ ์ด๋ฆ์ ์ค์
thread1.start();
// Runnable ์ธํฐํ์ด์ค ๋๋ค์์ผ๋ก ์ต๋ช
์ ์ค๋ ๋ ์์ฑ
Runnable th2 = () -> {
sharedValue.setValue(200);
};
Thread thread2 = new Thread(th2);
thread2.setName("์ค๋ ๋ 2");
thread2.start();
}
}
class SharedValue {
private int value = 0;
public int getValue() {
return value;
}
public synchronized void setValue(int value) { // synchronized ์ํ๋ฉด ๊ฐ์ด ๊นจ์ง.
this.value = value;
try {
sleep(2000);
} catch(InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + "์ ๊ฐ : " + getValue());
}
}
์ค๋ ๋ 1์ ๊ฐ : 100
์ค๋ ๋ 2์ ๊ฐ : 200
๐ก Thread ์ด๋ฆ ์์ฑ
๊ธฐ๋ณธ ์ค๋ ๋๋ thread.getName()์ ํตํด Thread-n์ด๋ผ๋ ์ด๋ฆ์ ๊ฐ์ง๋๋ค.
ํ์ง๋ง ์กฐ๊ธ ๋ ์์ํ ๋๋ฒ๊น ์ ์ํด thread.setName("์ค๋ ๋ ์ด๋ฆ")์ ํตํด ์ง์ ์ค์ ํ ์ ์์ต๋๋ค.
subThread1.setName("ํ
์คํธ ์ฐ๋ ๋");
subThread1.start();
โญ๋ฐ๋ชฌ ์ค๋ ๋(daemon thread)
- ๋ค๋ฅธ ์ค๋ ๋์ ์์ ์ ๋๋ ๋ณด์กฐ ์ค๋ ๋
- ๋ค๋ฅธ ์ค๋ ๋๊ฐ ๋ชจ๋ ์ข ๋ฃ๋๋ฉด ๋ฐ๋ชฌ ์ค๋ ๋๋ ๊ฐ์ ์ข ๋ฃ ๋จ
- start() ๋ฉ์๋ ํธ์ถ ์ ์ setDaemon(true)๋ฅผ ํธ์ถํด์ผ ํจโ
public class Main {
public static void main(String[] args) throws InterruptedException {
AutoSaveThread auto = new AutoSaveThread();
auto.setDaemon(true); // ๋ฐ๋ชฌ์ค๋ ๋ ์ค์
auto.start();
sleep(30000);
}
}
class AutoSaveThread extends Thread {
public void save() {
System.out.println("์์
๋ด์ฉ์ ์ ์ฅํจ");
}
@Override
public void run() {
while(true) {
try {
sleep(3000);
} catch (InterruptedException e) {
}
save();
}
}
}