728x90
반응형
728x90
참고 자료
1) 우테코 : https://www.youtube.com/watch?v=oazGbhBCOfU
2) 세마포어 자바소스 : https://blog.naver.com/vanillasea81/220405264484
반응형
이번 포스팅은 세마포어(Semaphore)와 뮤텍스(Mutex)에 대해 알아보겠습니다.
먼저 세마포어와 뮤텍스에 대해 알아보기 전, 몇가지 알아봐야할 것이 있습니다.
1. 교착 상태
- 두 가지 이상의 작업이 서로 상대방의 작업이 끝나기를 하염없이 기다리는 상태를 말한다.
- 서로 사용할 수 있는 공유된 리소스(종이, 연필) 등을 공유 자원 혹은 임계 영역이라 한다.
2. 임계 영역
- 임계 영역은 작업들이 리소스를 같이 사용할 수 있는 공유 자원이 있는 곳이므로 한 작업이 자원을 점유하면, 다른 자원은 리소스를 점유한 작업이 종료될 때까지 기다려야 한다.
3. 교착상태가 발생할 수 있는 4가지 조건
- 상호 배제(Mutual exclusion)
- 점유 대기
- 비선점
- 순환 대기
4. 상호 배제
- 상호 배제란 프로세스들이 필요로 하는 자원에 대해 배타적인 통제권을 요구하는 것
- 하나의 프로세스가 공유 자원을 사용할 때 다른 프로세스가 공유 자원에 접근하는 것을 통제하는 것
5. Mutex
- 여러 스레드를 실행하는 환경에서 자원에 대한 접근 제한을 강제하기 위한 동기화 매커니즘
Example) 화장실에 있는 유일한 변기칸(공유된 자원)
- 대변이 마려운 한명이 변기칸에 들어감
- 들어간 사람은 이제 변기칸에 다른 사람이 들어오지 못하도록 문을 걸어 잠굼(Lock)
- 대변이 마려운 새로운 사람이 화장실 도착, 유일한 변기칸에 진입을 시도
- 기존에 들어간 사람이 나올 때까지 기다려야 함
- 기존에 들어간 사람이 나올 때까지 기다리는 사람이 더 증가
Mutex는 대기큐를 생성해두고, 임계 영역에 스레드가 있을 경우 다른 스레드가 공유 자원을 사용하려고 한다면 스레드를 Blocking하고 대기큐에 Sleep 시킨다.
6. Spin Lock
- 화장실 변기칸에 Lock이 걸린 상태에서 언제 다 변을 보는지 물어보는 방법
- 대기하는 사람이 언제 끝나냐고 계속 물어보는 방식
- Busy Wating -> 점유한 프로세스가 대응하느라 다른 업무로 진행이 불가.
7. Spin Lock을 사용하면 좋을 때
- Context Switching이 짧을 때(문맥교환이 짧을 때)
- 멀티코어 프로세스일 때
8. 세마포어(Semaphore)
- 멀티 프로그래밍 환경에서 다수의 프로세스나 스레드의 여러개의 공유 자원에 대한 접근을 제한하는 방법으로 사용되는 동기화 기법
- 뮤텍스랑은 다르게, 여러 프로세스가 접근이 가능하다.
Example) 화장실 변기칸 여러 개
- 최대 3명까지 수용 가능, 다 점유시 0으로 표시
- 변기칸에 진입하는 사람은 P, 변기칸에서 나가는 사람은 V
- P = 기다리는 시간, V = 볼일 다 본 사람
- 대기자가 변기에 진입하면 또 다른 변기 대기자가 왔을 때
Sleep Wating -> 빈 자리 있을 시 Sleep 된 Thread를 깨움
Busy Wating -> 사용 가능한 자리가 생길 때까지 계속 물어보며 기다림 - 남은 자리가 음수이면 음수의 수 만큼 사람이 기다리는 중
※ 개념 정리
1) Mutex
- 여러 Thread를 사용하는 환경에서 자원에 대한 접근을 강제하기 위한 동기화 매커니즘이다.
- Boolean 타입의 Lock 변수를 사용한다.
- 공유 자원을 사용 중인 Thread가 있을 때, 다른 Thread가 공유 자원에 접근한다면 Blocking 후 대기 큐로 보낸다.
- Lock을 걸은 Thread만 Lock을 해제할 수 있다.
2) Spin Lock
- 기본적으로 Mutex와 유사함
- Busy-wating을 하며, 대기 큐를 갖지 않는다.
- Mutex-Non Blocking 모델로 볼 수 있다.
3) Semaphore
- 세마포어 변수를 통해 wait, signal을 관리한다. 세마포어 변수는 0 이상의 정수형 변수를 갖는다.
- 계수 세마포어로 사용할 수 있으며, 접근 가능한 공유 자원의 수가 1개일 때는 이진 세마포어로 Mutex처럼 사용할 수 있다.
- Lock을 걸지 않은 Thread도 Signal을 보내 Lock을 해제할 수 있다.
Mutex 자바 예제
Account.java
package mutex;
public class Account {
int balance = 1000;
// 정수를 매개변수로 받아서
// balance의 값보다 작거나 같으면
// balance에서 빼주는 메소드
// 돈을 찾는 메소드
public void withdraw(int money) {
if(balance >= money) {
try {
Thread.sleep(1000);
} catch (Exception e) {}
balance -= money;
}
}
}
Bank.java
package mutex;
// Thread로 사용할 클래스
public class Bank extends Thread{
// 여러 개의 객체가 공유해서 사용할 수 있는 변수
static Account obj = new Account();
// 문자열을 매개변수로 받아서 스레드의 이름으로
// 사용할 생성자
public Bank(String name) {
super(name);
}
// 스레드로 수행할 메소드
public void run() {
while(true) {
synchronized(obj) {
// 100 ~ 300을 랜덤하게 추출
int money = (int)(Math.random() * 1 + 3) * 100;
if(obj.balance >= money) {
System.out.println(getName() + "의 balance : " + obj.balance);
System.out.println(getName() + "의 찾는 금액 : " + money);
obj.withdraw(money);
System.out.println(getName() + "의 balance : " + obj.balance);
} else {
break;
}
}
}
}
}
MutexTest.java
package mutex;
public class MutexTest {
public static void main(String[] args) {
Bank th1 = new Bank("ATM");
Bank th2 = new Bank("은행");
th1.start();
th2.start();
}
}
Semaphore 자바 예제
SyncMulti.java
package semaphore;
import java.util.concurrent.Semaphore;
public class SyncMulti extends Thread{
Semaphore sem;
String msg;
public SyncMulti(Semaphore sem, String msg) {
super();
this.sem = sem;
this.msg = msg;
}
public void run() {
try {
sem.acquire(); // 실행한다.
System.out.println(msg);
Thread.sleep(5000); // 5초간 딜레이
sem.release(); // 끊어준다.
// 세마포어를 실행시키고 5초 후에는 세마포어를 끊어준다.
} catch (Exception e) {
// TODO: handle exception
}
}
}
SemaphoreTest.java
package semaphore;
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
public static void main(String[] args) {
Semaphore se = new Semaphore(3);
SyncMulti th1 = new SyncMulti(se, "1");
SyncMulti th2 = new SyncMulti(se, "2");
SyncMulti th3 = new SyncMulti(se, "3");
SyncMulti th4 = new SyncMulti(se, "4");
th1.start();
th2.start();
th3.start();
th4.start();
}
}
728x90
반응형
'자바 > 개념' 카테고리의 다른 글
[Java/개념] equals() 와 hashCode() (0) | 2024.01.19 |
---|---|
[Java/개념] 값 비교( '==' 동등 비교 vs equals() 객체 비교) (0) | 2023.03.08 |
[java] Garbage Collector(GC) - 가비지 컬렉터 (0) | 2021.09.18 |
[java] 자바 RMI(Remote Method Invocation) (0) | 2021.09.10 |
[java] 묵시적 형 변환 (0) | 2021.01.27 |
댓글