[Java] Thread ๊ธฐ์ด
1. ์ค๋ ๋์ ๊ฐ๋
์ ์ ์ธ ํ๋ก๊ทธ๋จ์ด ์์(CPU๋ ๋ฉ๋ชจ๋ฆฌ)์ ์ป์ด ์คํ ์ค์ ๋ค์ด๊ฐ ๊ฒ์ ํ๋ก์ธ์ค๋ผ ํ๋ฉฐ, ๋ชจ๋ ํ๋ก๊ทธ๋จ์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ๋ก์ธ์ค ๋จ์๋ก ์คํ๋๋ค. ์ค๋ ๋๋ ํ๋ก์ธ์ค ๋ด์ ์์ ์คํ ๋จ์์ด๋ฉฐ ํ๋ก์ธ์ค๋ ํ๋์ ์ค๋ ๋๋ก ๊ตฌ์ฑ๋๊ฑฐ๋ ์ฌ๋ฌ ๊ฐ์ ์์ ์ค๋ ๋๋ก ๊ตฌ์ฑ๋ ์ ์๋ค.
JAVA ํ๋ก๊ทธ๋จ์ ์คํ์ํค๋ฉด JVM ์์ ์๋์ผ๋ก ์ค๋ ๋๊ฐ ํ๋ ์์ฑ๋๊ณ ์ด๋ฅผ โ๋ฉ์ธ ์ค๋ ๋โ ๋ผ ํ๋ค. ๋ฉ์ธ ์ค๋ ๋ ๋ด์์ ์ฌ๋ฌ ์ค๋ ๋๋ฅผ ์์ฑํ๊ฑฐ๋ ์คํํ ์ ์๊ณ , ๋ชจ๋ ์ค๋ ๋๋ ์ฐ์ ์์(priority)๋ฅผ ๊ฐ์ง๋๋ฐ, ์ฒ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ ์ ์์ฑํ ์ค๋ ๋์ ๋์ผํ ์ฐ์ ์์๋ฅผ ๊ฐ์ง๊ณ ์์ฑ๋๋ค. ๊ฐ ์ค๋ ๋ ๋ณ ์ฐ์ ์์๋ฅผ ์์ผ๋ก ์ค์ ํ ์๋ ์๋ค. ์ด๋ ์ค๋ ๋๋ฅผ ์ถ์ํ ํ Thread ํด๋์ค๋ฅผ ์ด์ฉํ๋ค.
2. ์ค๋ ๋ ํด๋์ค
๋ค์์ ์๋ฐ ์ค๋ ๋ ํด๋์ค ๋ด๋ถ์ ์ฃผ์ ์์์ ์์ฑ์, ๊ทธ๋ฆฌ๊ณ ๋ฉ์๋๋ฅผ ์ดํด๋ณด์.
2-1. ์ฃผ์ ์์
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* ์ค๋ ๋์ ๋ฐ๋ชฌ ์ฌ๋ถ */
private boolean daemon = false;
/* ์ค๋ ๋์ ์ํ */
private volatile int threadStatus;
/* ์ค๋ ๋ ์ฐ์ ์์ ์ต์๊ฐ */
public static final int MIN_PRIORITY = 1;
/* ์ค๋ ๋ ์ฐ์ ์์ ๊ธฐ๋ณธ๊ฐ */
public static final int NORM_PRIORITY = 5;
/* ์ค๋ ๋ ์ฐ์ ์์ ์ต๋๊ฐ */
public static final int MAX_PRIORITY = 10;
2-2. ์ฃผ์ ์์ฑ์
1
2
3
4
5
6
7
8
/**
* 1. ์ค๋ ๋ ๊ทธ๋ฃน
* 2. Runnable Interface ๋ฅผ ์์๋ฐ๋ ์คํ ๋์
* 3. ์ค๋ ๋ ๋ค์ (๊ธฐ๋ณธ ๊ฐ์ผ๋ก "Thread-" + nextThreadNum() ํ์์ ๊ฐ์ง๋ค
*/
public Thread(ThreadGroup group, Runnable target, String name) {
this(group, target, name, 0);
}
2-3. ์ฃผ์ ๋ฉ์๋
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//ํ์ฌ ์คํ์ค์ธ ์ค๋ ๋๊ฐ this ์ค๋ ๋๋ฅผ ์ ์ดํ ๊ถํ์ด ์๋์ง ํ์ธํ๋ค.
//์๋ค๋ฉด SecurityException ์ ๋ฐํํ๋ค.
public final void checkAccess() {...}
//this ์ค๋ ๋์ ์ฐ์ ์์๋ฅผ ์ค์ ํ๋ค.
public final void setPriority(int newPriority) {...}
//์คํ ์ค๋จ์ํ์ ์๋ this ์ค๋ ๋๋ฅผ ๊นจ์ด๋ค.
public void interrupt() {...}
//this ์ค๋ ๋๊ฐ ์ข
๋ฃ๋ ๋ ๊น์ง ๊ธฐ๋ค๋ฆฌ๊ฑฐ๋ ์ง์ ๋ ์๊ฐ(milllis) ๋งํผ ๊ธฐ๋ค๋ฆฐ๋ค.
public final synchronized void join() throws InterreptedException {...}
public final synchronized void join(long millis) throws InterreptedException {...}
//ํ์ฌ ์คํ์ค์ธ ์ค๋ ๋๋ฅผ ์ผ์์ ์ผ๋ก ๋ฉ์ถ๊ฒ ํด์ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์คํ๋๋๋ก ํ๋ค.
public static void yeild() {...}
//ํ์ฌ ์ค๋ ๋๋ฅผ ์ง์ ๋ ์๊ฐ(millis) ๋งํผ ์คํ์ ๋ฉ์ถ๋ค.
public static void sleep(long millis) {...}
2-4. Object ํด๋์ค์ ์ค๋ ๋ ๊ด๋ จ ์ฃผ์ ๋ฉ์๋
1
2
3
4
5
6
7
//ํ์ฌ ์ค๋ ๋๋ฅผ ๋ค๋ฅธ ์ค๋ ๋๊ฐ notify() ํน์ notifyAll() ์ ํธ์ถํ ๋๊น์ง ๋๊ธฐ์ํจ๋ค.
public final native void wait() throws InterruptedException;
public final native void wait(long timeoutMillis) throws InterruptedException;
//๋๊ธฐ์ค์ธ ์ค๋ ๋๋ฅผ ํ๋ ํน์ ๋ชจ๋ ๊นจ์ด๋ค.
public final native void notify();
public final native void notifyAll();
3. ์ค๋ ๋์ ์์ฑ
์ค๋ ๋์ ์์ฑ์๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค. Thread
ํด๋์ค๋ฅผ ์์๋ฐ๊ฑฐ๋ Runnable
์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๋ก ์์ฑํ๋ ๋ฐฉ๋ฒ์ด ์๋ค. JAVA๋ ๋ค์ค์์์ด ๋ถ๊ฐ๋ฅํ๋ฏ๋ก ๋ค๋ฅธ ํด๋์ค๋ฅผ ์์๋ฐ์ผ๋ฉด์ ์ค๋ ๋๋ก ์คํํ๊ธฐ ์ํด์๋ Runnable
์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๋ก ์ฌ์ฉํด์ผ ํ๋ค.
3-1. Thread ํด๋์ค๋ฅผ ์์๋ฐ๊ธฐ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Scratch {
public static void main(String[] args) {
MyThread thread = new MyThread();
// 3.start() ๋ฉ์๋๋ฅผ ํตํด ์คํํ๋ค.
thread.start();
}
}
//1. Thread ํด๋์ค๋ฅผ ์์๋ฐ๋ ํด๋์ค๋ฅผ ์ ์ํ๋ค.
class MyThread extends Thread {
// 2. run() ๋ฉ์๋๋ฅผ ์ฌ์ ์ํ๋ค.
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("[" + this.getName() + "]i = " + i);
}
}
}
3-2. Runnable ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ธฐ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Scratch {
public static void main(String[] args) {
// 3.Runnable ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ์ธ์คํด์ค๋ฅผ ํ๋ผ๋ฏธํฐ๋ก Thread ํด๋์ค๋ฅผ ์์ฑํ๋ค
Thread thread = new Thread(new MyThread());
// 4.start() ๋ฉ์๋๋ฅผ ํตํด ์คํํ๋ค.
thread.start();
}
}
//1. Runnable ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๋ก ์์ฑํ๋ค.
class MyThread implements Runnable {
// 2. run() ๋ฉ์๋๋ฅผ ์ฌ์ ์ํ๋ค.
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("i = " + i);
}
}
}
3-EX. Thread ๋ฉ์๋์ start() ๋ฉ์๋๋ฅผ ํตํด์๋ง ์คํ์์ผ์ผ ํ๋ ์ด์
Runnable
์ธํฐํ์ด์ค์ run()
๋ฉ์๋๋ฅผ ์ง์ ์คํ์ํค์ง ์๋ ์ด์ ๋ Thread
๊ฐ์ฒด์ start()
๋ฉ์๋๋ฅผ ํตํด์๋ง JVM์ด ์๋ก์ด ์ค๋ ๋๋ฅผ ์์ฑํ๊ณ run()
๋ฉ์๋ ์์ญ์ ์ฝ๋๋ฅผ ์คํ์ํค๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ฅ run()
๋ฉ์๋๋ฅผ ์คํ์ํจ๋ค๋ฉด ์๋ก์ด ์ค๋ ๋๋ฅผ ์์ฑํ์ง ์๊ณ ์ฑ๊ธ ์ค๋ ๋ ์์ญ์์ run()
๋ฉ์๋์ ๋ด์ฉ๋ง์ ์คํ์ํจ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Scratch {
public static void main(String[] args) {
MyThread thread1 = new MyThread();
thread1.run();
MyThread thread2 = new MyThread();
thread2.run();
System.out.println("===== main end =====");
}
}
class MyThread implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println("[" + Thread.currentThread().getName() + "] i = " + i);
}
}
}
4. ์ค๋ ๋์ ์ํ
๋ค์์ ์ค๋ ๋๊ฐ ์์ฑ๋๊ณ CPU์ ์์์ ์ป์ด ์คํ ๋ ํ, ์ข ๋ฃ ์ํ์ ์ด๋ฅด๊ธฐ๊น์ง ๊ฐ์ง ์ ์๋ ์ํ๋ค์ด๋ค.
4-1. Startable ์ํ
Thread ํด๋์ค๋ฅผ ์์ฑํ์ฌ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ํ์ด๋ค. ์ฆ, start() ๋ฉ์๋ ํธ์ถ ๋ฐ๋ก ์ง์ ์ ์ํ์ด๋ค. ๋ชจ๋ ์ค๋ ๋๋ Startable ์ํ์์๋ง Runnable ์ํ๋ก ๋์ด๊ฐ ์ ์๋ค.
4-2. Runnable ์ํ
Running ์ํ์ ๋ฐ๋ก ์ง์ ์ํ์ด๊ณ , ์คํ์ ์ํ ๋ชจ๋ ์ค๋น๊ฐ ๋๋ฌ์ผ๋ฉฐ CPU ์์๋ง ์ป์ผ๋ฉด ๋ฐ๋ก ์คํํ ์ ์๋ ์ํ๋ฅผ ์๋ฏธํ๋ค.
4-3. Running ์ํ
์ค๋ ๋์ ์ ์๋ run() ๋ฉ์๋๊ฐ ์ค์ ๋ก ์คํ๋๊ณ ์๋ ์ํ์ด๋ค.
4-4. Not Running ์ํ
Running ์ํ์์ CPU ์์์ ์์ด ์คํ์ด ์ค๋จ๋ ์ํ์ด๋ค. ์คํ์ ์ค๋จ์ํค๋ ๋ฐฉ๋ฒ์ ์ค์ค๋ก Thread ํด๋์ค์ sleep() ๋ฉ์๋๋ Object ํด๋์ค์ wait() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒ์ด๋ค.
4-5. Dead ์ํ
์ค๋ ๋๊ฐ ์ข ๋ฃ๋ ์ํ๋ฅผ ์๋ฏธํ๋ค. ์ข ๋ฃ๋ ์ค๋ ๋๊ฐ ๋ค์ ์์ํ๋ ค๋ฉด ๋ฐ๋์ Startable ์ํ๋ฅผ ๊ฑฐ์ณ์ผ ํ๋ค.
5. ์ค๋ ๋์ ์ ์ด
์ค๋ ๋์ ์ ์ด๋ ์ค๋ ๋์ ์ํ๋ฅผ ๋ณ๊ฒฝ์ํค๋ ๊ฒ์ ์๋ฏธํ๋ค. ์ค๋ ๋๋ฅผ ์ ์ดํ ๋ ์ฃผ์์ ์ ๊ฐ๊ธ์ ์ค๋ ๋๋ฅผ ์ง์ ์ข ๋ฃ์ํค๋ ๊ฒ์ ํผํ๋ ๊ฒ์ด ์ข๋ค.
5-1. ์ฐ์ ์์๋ฅผ ํตํ ์ ์ด
์ ๋์ ์ธ ๋์ ์์๋ฅผ ๋ณด์ฅํ์ง๋ ์์ง๋ง ์ฐ์ ์์๊ฐ ๋์ ์ค๋ ๋๋ ๋ฎ์ ์ค๋ ๋์ ๋นํด ์๋์ ์ผ๋ก CPU ์์์ ์ป์ ์ ์๋ ํ๋ฅ ์ด ๋์ผ๋ฏ๋ก ์ฐ์ ์์๋ฅผ ํตํด ์ ์ดํ ์ ์๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Scratch {
public static void main(String[] args) {
Thread threadMIN = new Thread(new MyThread("MIN"));
Thread threadNORM = new Thread(new MyThread("NORM"));
Thread threadMAX = new Thread(new MyThread("MAX"));
//์ฐ์ ์์ ๋ฎ์
threadMIN.setPriority(Thread.MIN_PRIORITY);
//์ฐ์ ์์ ์ค๊ฐ
threadNORM.setPriority(Thread.NORM_PRIORITY);
//์ฐ์ ์์ ๋์
threadMAX.setPriority(Thread.MAX_PRIORITY);
threadMIN.start();
threadNORM.start();
threadMAX.start();
}
}
class MyThread implements Runnable {
private String threadName;
public MyThread(String threadName) {
this.threadName = threadName;
}
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
}
System.out.println("[" + threadName + "] END");
}
}
5-2. Thread ํด๋์ค์ ๋ฉ์๋๋ฅผ ํตํ ์ ์ด
Thread ํด๋์ค์ yield(), join(), interrupt() , sleep() ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ์ค๋ ๋๋ฅผ ์ ์ดํ ์ ์๋ค.
yield() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์์ฃผ ์งง์ ์๊ฐ๋์ ์ค๋ ๋๊ฐ Runnable ์ํ๋ก ๋ค์ด๊ฐ์ ๋ค๋ฅธ ์ค๋ ๋์ CPU๋ฅผ ์๋ณดํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Scratch {
public static void main(String[] args) {
Thread thread1 = new Thread(new MyThread(), "thd1");
Thread thread2 = new Thread(new MyThread(), "thd2");
thread1.start();
thread2.start();
}
}
class MyThread implements Runnable {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
for (int i = 1; i <= 100; i++) {
System.out.print("[" + threadName + "] ");
if (threadName.equals("thd1")) Thread.yield();
}
}
}
join() ๋ฉ์๋๋ฅผ ์ด์ฉํ๋ ๊ฒฝ์ฐ ํน์ ์ค๋ ๋๊ฐ ๋๋ ๋๊น์ง ์ค๋ ๋๋ฅผ ๋๋ด์ง ์๊ณ ๋ฉ์ถ๊ฒ ํ ์ ์๋ค. join() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ๋์๋ InterruptedException
์์ธ์ฒ๋ฆฌ๋ฅผ ํด ์ฃผ์ด์ผ ํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Scratch {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new MyThread(), "thd1");
Thread thread2 = new Thread(new MyThread(), "thd2");
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("==== main end ====");
}
}
class MyThread implements Runnable {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
for (int i = 1; i <= 5; i++) {
System.out.println("[" + threadName + "] ");
}
}
}
์ด๋ฒ์๋ ํน์ ์ค๋ ๋๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ฒ ํ๋ ๊ฒ์ด ์๋๋ผ, ๋๊ธฐ์ํ์ ์๋ ์ค๋ ๋๋ฅผ ๊นจ์ฐ๋(Not Running โ Running) interrupt() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ฅผ ์ดํด๋ณด์.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class Scratch {
public static void main(String[] args) throws InterruptedException {
MyThread thread1 = new MyThread("thread1");
MyThread thread2 = new MyThread("thread2");
MyThread thread3 = new MyThread("thread3");
thread1.setNextThread(thread2);
thread2.setNextThread(thread3);
thread3.setNextThread(thread1);
thread1.start();
thread2.start();
thread3.start();
try {
//InterruptedException ์ ๋ฐ์์ํจ๋ค.
thread1.interrupt();
thread1.join();
thread2.join();
thread3.join();
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println("===== main end =====");
}
}
class MyThread extends Thread {
private Thread nextThread;
public MyThread(String threadName) {
super(threadName);
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000000);
} catch(InterruptedException e) {
System.out.print("[" + threadName + "] -> ");
//๋ค์ ์ค๋ ๋๋ฅผ ๊นจ์ด๋ค.
if(nextThread.isAlive()) nextThread.interrupt();
}
}
}
public void setNextThread(Thread nextThread) {
this.nextThread = nextThread;
}
}
์์ ์ฝ๋๋ sleep ์ํ์ ์๋ ์ค๋ ๋๋ฅผ ์์ฐจ์ ์ผ๋ก interrupt ํ๋ฉด์ ์ค๋ ๋์ ํ๋ฆ์ ์ ์ดํ๋ ์ฝ๋์ด๋ค.
6. ์ค๋ ๋ ๋๊ธฐํ
ํ๋์ ์์์ ๊ณต์ ํ๋ ์ฌ๋ฌ ์ค๋ ๋ ๊ฐ์ ๋๊ธฐํ๋ฅผ ํ์ง ์์ผ๋ฉด ๊ฐ์ญ ํ์์ด ๋ฐ์ํ๋ค. ๊ฐ์ญ ํ์์ด๋ ๊ณต์ ์์์ ์ผ๊ด์ฑ์ด ๊นจ์ง๋ ๊ฒ์ ์๋ฏธํ๋ค.
๊ฐ๋จํ ์๋ก ๊ณต์ ์์์ ์ผ๊ด์ฑ์ด ๊นจ์ง๋ ์ํฉ์ ์ดํด๋ณด์.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class Counter {
private int c = 0;
public void increment() {
System.out.println("[" + Thread.currentThread().getName() + "] " + (++c));
}
public int getValue() {
return c;
}
}
class CounterRunner implements Runnable {
private final Counter c;
public CounterRunner(Counter c) {
this.c = c;
}
public void run() {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(500);
c.increment();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Scratch {
public static void main(String[] args) throws InterruptedException {
Counter c = new Counter();
Thread threadA = new Thread(new CounterRunner(c), "A");
Thread threadB = new Thread(new CounterRunner(c), "B");
threadA.start();
threadB.start();
threadA.join();
threadB.join();
System.out.println("c = " + c.getValue());
}
}
์ค๋ ๋ ๋๊ฐ๊ฐ ํ๋์ ๊ณต์ ์์(Counter ๊ฐ์ฒด)์ ์ ๊ทผํด ๋ณ์์ ๊ฐ์ ์กฐ์ํ๊ณ ์๋ค. ์ ์์ ์ผ๋ก ๊ธฐ๋ํ ์ ์๋ ๊ฐ์ ๋ ์ค๋ ๋๊ฐ ๊ฐ๊ฐ ๋ค์ฏ ๋ฒ์ฉ ๊ฐ์ฒด์ ๊ฐ์ ์ฆ๊ฐ์์ผฐ์ผ๋ฏ๋ก 10์ด์ง๋ง ์ค์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์.
๊ฒฐ๊ณผ๋ ๋งค๋ฒ ๋ค๋ฅด์ง๋ง(์ ์์ ์ธ ๊ฒฐ๊ณผ๊ฐ ๋์ฌ๋๋ ์๋ค), ์ฌ๋ฐ๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฅํ์ง ๋ชปํ๋ค๋ ๊ฒ์ ์ ์ ์๋ค.
์ด๋ ๊ฒ ๋ณ๋ ฌ ์ค๋ ๋๊ฐ์ ๊ฐ์ญ ํ์์ผ๋ก ์ธํด ์ผ๊ด์ฑ์ ํด์น๋ ๋ฌธ์ ๋ฅผ ๋์์ฑ ์ด์(Concurrency Issue)๋ผ๊ณ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ฌํ ๋์์ฑ ์ด์๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด synchronized ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
synchronized
ํค์๋๋ ๋ค์๊ณผ ๊ฐ์ ๋ฒ์์์ ์ฌ์ฉํ ์ ์๋ค.
- ์ธ์คํด์ค ๋ฉ์๋
- ์ ์ ๋ฉ์๋
- ์ฝ๋ ๋ธ๋ก
JAVA๋ ๋๊ธฐํ๋ฅผ ์ํด ๋ชจ๋ํฐ๋ผ๋ ๋๊ธฐํ ๊ธฐ๋ฒ์ ์ฌ์ฉํ๋ค. ๋ชจ๋ํฐ ๊ธฐ๋ฒ์ ์ฝ๊ฒ ๋งํ๋ฉด synchronized
๋ก ์ ์ธ๋ ์์ญ ๋ด์๋ ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง ์ง์
ํ๋๋ก ํ์ฉํ๋ ๊ธฐ๋ฒ์ด๋ค. ๋ชจ๋ํฐ์ ํน์ ์ค๋ ๋๊ฐ ์ง์
ํ๋ฉด ๋ชจ๋ํฐ ๋ฝ์ ํ๋ํ๊ณ ๊ทธ ์ธ์ ์ค๋ ๋๋ ํ์์ ๋๊ธฐํ๋ค.
์์ ์ฝ๋์ synchronized
ํค์๋๋ฅผ ์ ์ฉํด๋ณด์.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// ...
// Counter.class
public synchronized void increment() {
System.out.println("[" + Thread.currentThread().getName() + "] " + (++c));
}
// ...
// ...
// Counter.class
public void increment() {
synchronized (this) {
System.out.println("[" + Thread.currentThread().getName() + "] " + (++c));
}
}
// ...
๋ค์๊ณผ ๊ฐ์ด ์ธ์คํด์ค ๋ฉ์๋ ์ ์ฒด๋ฅผ ๋๊ธฐํ ์์ญ์ผ๋ก ๋ง๋ค๊ฑฐ๋, ํน์ ์ฝ๋๋ง ๋๊ธฐํ ์์ ์ผ๋ก ์ํํ๋ ๋๊ธฐํ ๋ธ๋ญ์ ๋ง๋ค์ด ์ค ์ ์๋ค. ๋๊ธฐํ ์์ญ์ ์ง์ ํ ํ ์์ ์ฝ๋๋ฅผ ๋ค์ ํ๋ฒ ์คํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค.
Refferences
- ๐Guide to the Synchronized Keyword in Java - Baeldung
- ๐What is a Monitor in Computer Science? - Baeldung
- ๐Guide to the Synchronized Keyword in Java - Baeldung
- ๐๋ชจ๋ํฐ(๋๊ธฐํ) - ์ํค๋ฐฑ๊ณผ
- KNOU - JAVA ํ๋ก๊ทธ๋๋ฐ 11๊ฐ ๋ฉํฐ ์ค๋ ๋ ํ๋ก๊ทธ๋๋ฐ