1. 동기화
1-1. method 전체를 임계 영역으로 지정하는 방법
1-2. 특정한 영역을 영역으로 지정하는 방법
- method 내의 코드 일부를 { }로 감싸고 중괄호 앞에 synchronize(참조변수)를 붙힌다.
이 때 참조변수는 lock을 걸고자 하는 객체를 참조하는 것.
2. wait() & notify()
- 동기화된 임계 영역의 코드를 수행하다가 작업을 더이상 진행할 상황이 아니면
일단 wait()을 호출하여 thread가 lock을 반납하고 기다리게 한다.
그러면 다른 thread가 lock을 얻어 해당 객체에 대한 작업을 수행할 수 있게 된다.
나중에 작업을 진행할 수 있는 상황이 되면 notify()를 호출해서
작업을 중단했던 thread가 다시 lock을 얻어 작업을 진행할 수 있게 한다.
- wait과 notiry(notifyAll) method는 동기화 처리를 해서, 한순간에 하나의 thread만 호출이 가능하도록 한다.(동시호출 아님)
3. Multi thread 사용하여 ATM기에서 번갈아가며 돈을 빼는 프로그램을 만들어보장.
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 |
class ATM implements Runnable { //완전추상객체 interface를 받는거/ runnable은 thread를 돌릴 수 있는 환경 제공
private long depositeMoney = 10000;
public void run() {
synchronized (this) { //자기 자신의 class 내에서 동기화 하겠다.
for (int i = 0; i < 10; i++) {
notify(); //notify() : thread의 제어권을 넘겨준당. // 처음에는 withdraw 한번 돌고 제어권 넘기고 wait.
try {
wait();
Thread.sleep(1000); //1초 지연
} catch (InterruptedException e) { //예외처리
e.printStackTrace();
}
if (getDepositeMoney() <= 0)
break;
withDraw(1000); // withDraw 함수 호출
}
}
}
public void withDraw(long howMuch) {
ATM atm = new ATM(); //객체 생성
if (getDepositeMoney() > 0) { //돈 1000원씩 까임
depositeMoney -= howMuch;
System.out.print(Thread.currentThread().getName()+ " , ");
System.out.printf("잔액 : %,d 원 %n",getDepositeMoney());
} else { // 1000원 이하로 있을 때
System.out.print(Thread.currentThread().getName()+ " , ");
System.out.println("잔액이 부족합니다.");
}
}
public long getDepositeMoney() { //get
return depositeMoney;
}
}
public class SynchronizedEx {
public static void main(String[] args) {
ATM atm = new ATM();
Thread mother = new Thread(atm, "mother"); //엄마 thread 생성, atm에서 thread를 만들어서 돌려라
Thread son = new Thread(atm, "son");
mother.start();
son.start(); //thread가 엄마꺼 아들꺼 두개 돌아감.
}
} |
cs |
- main에서 mother thread가 먼저 호출될지 son thread가 먼저 호출 될지는 알 수 없다.
- 7번 줄에서 notify() 가 호출됐을 때, 먼저 호출된 함수의 제어권이 다음 함수로 넘어가며,
먼저 호출된 함수는 wait()함수에 의해 잠시 block 상태가 된다.
for문이 끝날 때 까지 계속 반복하여 중복없이 번갈아 가며 1000원씩 빠져나갈 수 있게 된다.
-결과화면
4. join()
- 해당 작업의 수행이 끝날 때까지 기다렸다가, 수행이 끝나면 그 결과를 반환한다. 비동기 method이다.
- 비동기 method : 일반적인 method와 달리 method를 호출만 할 뿐, 그 결과를 기다리지 않는다.
내부적으로는 다른 thread에게 작업을 수행하도록 지시만 하고 결과를 기다리지 않고 돌아오는 것.
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 |
class MyRunnableTwo implements Runnable{
public void run(){
System.out.println("run");//2
first();
}
public void first(){
System.out.println("first");//3
second();
}
public void second() {
System.out.println("second");//4
}
}
public class JoinEx {
public static void main(String []args){
System.out.println(Thread.currentThread().getName()+" start");//1
Runnable r = new MyRunnableTwo(); //Runnable r class 생성 후 호출
Thread myThread = new Thread(r); //r Thread를 실행시킨다.
myThread.start(); //시작
try{
myThread.join(); //모든 Thread가 돌 동안 main이 끝나지 않음
}catch(InterruptedException ie){
ie.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" end"); //5
}
}
// 주석에 써진 숫자 순서대로 출력된다. |
cs |
'Java > Java' 카테고리의 다른 글
[Java] thread_1 (0) | 2017.09.04 |
---|