File tree 4 files changed +79
-14
lines changed
src/main/java/io/concurrency/chapter06/exam02
4 files changed +79
-14
lines changed Original file line number Diff line number Diff line change @@ -15,7 +15,7 @@ public synchronized void acquired() {
15
15
}
16
16
17
17
public synchronized void release () {
18
- this .signal = 1 ;
19
- this .notify ();
18
+ this .signal = 1 ; //다른 스레드들이 사용 가능함을 설정
19
+ this .notify (); // 모든 대기 스레드 중 임의로 선택한 스레드 하나만 깨움.
20
20
}
21
21
}
Original file line number Diff line number Diff line change @@ -9,20 +9,34 @@ public CountingSemaphore(int permits) {
9
9
this .signal = permits ;
10
10
}
11
11
12
- public void acquired () {
13
- synchronized (this ) {
14
- while (this .signal == 0 ) {
15
- try {
16
- wait ();
17
- } catch (InterruptedException e ) {
18
- e .printStackTrace ();
19
- }
12
+
13
+ public synchronized void acquired (){
14
+ while (this .signal ==0 ){
15
+ try {
16
+ wait ();
17
+ } catch (InterruptedException e ) {
18
+ throw new RuntimeException (e );
20
19
}
21
- this .signal --;
22
20
}
23
- System .out .println (Thread .currentThread ().getName () + " 락 획득, 현재 세마포어 값: " + signal );
21
+ this .signal --;
22
+ System .out .println (Thread .currentThread ().getName () + ": 락 획득, 현재 세마포어 값: " +signal );
24
23
}
25
24
25
+ // public void acquired() {
26
+ // synchronized (this) {
27
+ // while (this.signal == 0) {
28
+ // try {
29
+ // wait();
30
+ // } catch (InterruptedException e) {
31
+ // e.printStackTrace();
32
+ // }
33
+ // }
34
+ // this.signal--;
35
+ // }
36
+ // System.out.println(Thread.currentThread().getName() + " 락 획득, 현재 세마포어 값: " + signal);
37
+ // }
38
+
39
+
26
40
public synchronized void release () {
27
41
if (this .signal < permits ) { // signal 값이 permits 보다 작을 때만 증가
28
42
this .signal ++;
Original file line number Diff line number Diff line change 3
3
public class CountingSemaphoreExample {
4
4
public static void main (String [] args ) {
5
5
6
- int permits = 10 ; // 최대 3개의 스레드가 동시에 작업을 수행할 수 있습니다.
6
+ int permits = 3 ; // 최대 3개의 스레드가 동시에 작업을 수행할 수 있습니다.
7
7
CountingSemaphore semaphore = new CountingSemaphore (permits );
8
8
SharedResource resource = new SharedResource (semaphore );
9
9
10
- int threadCount = 5 ; // 전체 스레드 개수
10
+ int threadCount = 10 ; // 전체 스레드 개수
11
11
12
12
Thread [] threads = new Thread [threadCount ];
13
13
for (int i = 0 ; i < threadCount ; i ++) {
Original file line number Diff line number Diff line change
1
+ ## Semaphore
2
+
3
+ - 세마포어: 공유 자원에 대한 접근 제어를 위한 신호 전달 메커니즘 동기화 도구
4
+ - S: 공유 자원 개수
5
+ - S > 0 -> 공유 자원 접근 허용
6
+ - S <= 0 -> 공유 자원 접근 거부
7
+ - P: 스레드 진입 여부 결정 (wait 연산)
8
+ - V: 대기 중인 스레드를 깨우는 (signal 연산) <br >
9
+
10
+ ---> 같은 세마포어의 P,V 함수의 S 연산은 원자적 실행이 보장되어야 한다(보장된다)
11
+
12
+
13
+ Mutex는 락을 획득하고 해제한 스레드가 동일해야 하지만<br >
14
+ Semaphore는 락을 획득하고 해제한 스레드가 같지 않아도 된다
15
+
16
+ Mutex는 기본적으로 잠긴 상태로 초기 시작되지만, 세마포어는 초기값 설정을 통해 공유 자원에 몇 개의 동시 스레드를 허용할 것인지 설정할 수 있다
17
+
18
+ 이진 세마포어를 구현한다면 Mutex와 동일하게 구현 가능
19
+
20
+ Mutex가 상호 배제 목적에 더 부합하고, Semaphore는 주로 리소스의 한정적 사용을 제한하는데 부합하다
21
+
22
+
23
+ ex) 이진 세마포어
24
+
25
+ ``` java
26
+ public class BinarySemaphore implements CommonSemaphore {
27
+ private int signal = 1 ;
28
+
29
+ public synchronized void acquired () {
30
+ while (this . signal == 0 ) {
31
+ try {
32
+ wait();
33
+ } catch (InterruptedException e) {
34
+ Thread . currentThread(). interrupt(); // 현재 스레드의 인터럽트 상태를 설정
35
+ }
36
+ }
37
+ this . signal = 0 ;
38
+ }
39
+
40
+ public synchronized void release () {
41
+ this . signal = 1 ; // 다른 스레드들이 사용 가능함을 설정
42
+ this . notify(); // 모든 대기 스레드 중 임의로 선택한 스레드 하나만 깨움.
43
+ }
44
+ }
45
+ ```
46
+
47
+ synchronized가 붙은 메서드가 호출되면 해당 객체의 다른 synchronized가 붙은 어떤 메서드들도 호출될 수 없다
48
+ 따라서 release()의 원자적 실행이 보장되며, 이는 V연산(signal)의 원자적 실행을 보장하는 것이다
49
+ 임계 영역을 끝낸 스레드는 acquired()에 의해 wait 중인 대기 스레드들 중 하나를 notify()함으로써 다른 스레드의 진입을 허용한다
50
+
51
+
You can’t perform that action at this time.
0 commit comments