쓰레드
: process 실행 중인 프로그램이 실행되면 OS로 부터 메모리를 할당받아 프로세스 상태가 됨
쓰레드 하나의 프로세스는 하나 이상의 쓰레드를 가지게 되고, 실제 작업을 수행하는 단위는 쓰레드임
Process(1.thread, 2.thread)
멀티 쓰레드
: 여러 쓰레드가 동시에 수행되는 프로그래밍, 여러 작업이 동시에 실행되는 효과
쓰레드는 각각 자신만의 작업공간을 가짐(context)
각 쓰레드 사이에서 공유하는 자원이 있음(자바에서는 static instance)
웹에서는 웹서버가 여러 request를 받아 처리함으로 멀티쓰레드역할을 함
여러 쓰레드가 자원을 공유하여 작업이 수행되는 경우 서로 자원을 차지하려는 race condition이 발생
이렇게 여러 thread가 공유하는 자원중 경쟁이 발생하는 부분은 critical section이라고 함
Context Context
[1.Thread] ---------> [Shared Resource] <---------- [2.Thread]
Critical section에 대한 동기화를 구현하지 않으면 오류 발생- 동기화(순차적 수행으로 Lock)로 처리
1. 쓰레드 Extends 방법
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
|
public class Athread extends Thread{
// 쓰레드 상속시 사용하는 메소드 run()
// 쓰레드가 사용시 불리는 메소드
public void run() {
for(int i=0;i<200;i++) {
System.out.print(i+" ");
}
System.out.println();
}
public static void main(String args[]) {
// 3개의 쓰레드 사용
// 1. 메인 쓰레드
System.out.println("Start : "+Thread.currentThread());
// Start : Thread[main,5,main] 쓰레드[호출함수,우선순위,소속된함수]
// 2. 쓰레드
Athread a = new Athread();
// 3. 쓰레드
Athread b = new Athread();
a.start();
b.start();
System.out.println("End : "+Thread.currentThread());
}
}
|
cs |
2. Implements 방법
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
|
public class Bthread implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<200;i++) {
System.out.print(i+" ");
}
System.out.println();
}
public static void main(String args[]) {
System.out.println("Start : "+Thread.currentThread());
Bthread run = new Bthread();
// runnable 객체를 받음
Thread b = new Thread(run);
Thread c = new Thread(run);
b.start();
c.start();
System.out.println("End : "+Thread.currentThread());
// 익명 클래스 사용
Runnable r1 = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("\n익명 thread");
}
};
r1.run();
}
}
|
cs |
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
|
public class TerminateThread extends Thread{
private boolean flag = false;
int i;
public TerminateThread(String name) {
super(name);
}
public void run() {
while(!flag) {
try {
sleep(1000);
}catch(InterruptedException e) {
}
}
System.out.println(getName()+ " end");
}
public void setFlag(boolean flag) {
this.flag=flag;
}
public static void main(String arg[]) throws IOException {
TerminateThread ta = new TerminateThread("A");
TerminateThread tb = new TerminateThread("B");
TerminateThread tc = new TerminateThread("C");
ta.start();
tb.start();
tc.start();
int in;
while(true) {
in = System.in.read();
if(in=='A') {
ta.setFlag(true);
}else if(in=='B') {
tb.setFlag(true);
}else if(in=='C') {
tc.setFlag(true);
}else if(in=='M') {
ta.setFlag(true);
tb.setFlag(true);
tc.setFlag(true);
break;
}
}
System.out.println("main");
}
}
|
cs |
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
|
public class JoinTest extends Thread{
int start;
int end;
int total;
public JoinTest(int start, int end) {
this.start=start;
this.end=end;
}
public void run() {
int i;
for(i=start;i<=end;i++) {
total += i;
}
}
public static void main(String args[]) {
// 메인 쓰레드 1개
// j1, j2 쓰레드 각각 1개
// 총 3개의 쓰레드
// 실행때마다 total의 값이 다르게 나온다
// join()을 걸어 알맞는 값이 나오게 한다
JoinTest j1 = new JoinTest(1,50);
JoinTest j2 = new JoinTest(51,100);
j1.start();
j2.start();
// 메인에서 j1,j2를 조인걸어서 끝낼때까지 NotRunnable상태로 만든다
try {
j1.join();
j2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int jTotal = j1.total + j2.total;
System.out.println(j1.total);
System.out.println(j2.total);
// 나중에 값을 체크하는 쓰레드인 메인쓰레드의 jTotal
System.out.println(jTotal);
}
}
|
cs |
멀티 스레드 동기화
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
class ParkBank{
private int money = 1000;
//public void saveMoney(int save) {
public synchronized void saveMoney(int save) {
// synchronized block 방식
// this 안에 객체
// 메소드가 실행하는동안 객체를 Lock 을 실행
// Thread 클래스 안에서 사용할 수 있다 Thread 클래스 안에 들어갈 경우
// 객체는 share resource 가 된다
//synchronized(this) {
// Lock을 걸 메소드 내용
//}
int m = getMoney();
try {
Thread.sleep(3000);
}catch(InterruptedException e) {
}
setMoney(m+save);
}
//public void minusMoney(int minus) {
public synchronized void minusMoney(int minus) {
int m = getMoney();
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
}
setMoney(m-minus);
}
public void setMoney(int money) {
this.money=money;
}
public int getMoney() {
return money;
}
}
class Park extends Thread{
public void run() {
// synchronized(SyncTest.myBank){ ... }
System.out.println("Start save");
SyncTest.myBank.saveMoney(3000);
System.out.println("myBank : "+SyncTest.myBank.getMoney());
}
}
class Wife extends Thread{
public void run() {
System.out.println("Start minus");
SyncTest.myBank.minusMoney(1000);
System.out.println("myBank : "+SyncTest.myBank.getMoney());
}
}
public class SyncTest {
// share resource
public static ParkBank myBank = new ParkBank();
public static void main(String args[]) {
Park p = new Park();
p.start();
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Wife w = new Wife();
w.start();
}
}
|
cs |
'OOP > Java' 카테고리의 다른 글
Java JUnit vs Spring JUnit (0) | 2022.12.20 |
---|---|
객체지향 4대 특성 (0) | 2022.07.31 |
직렬화 (0) | 2022.05.29 |
보조 스트림 클래스 (0) | 2022.05.25 |
문자 단위 스트림 (0) | 2022.05.22 |