JAVA 병발, 고전 자물쇠 사례 - 철학가 식사
17012 단어 자바 병발
자물쇠 고전 사례: 철학 자 식사.
이 사례 는 자 물 쇠 를 초래 할 것 이다.
라 는 책의 사례 를 수정 하여 실험 을 하면 코드 가 이해 하기 쉽 고 결과 도 상대 적 으로 통제 하기 쉽다.
첨부 코드:
젓가락 종류:
1 package com.tyxh.ch21.c6;
2
3 public class Chopstick {
4 private boolean taken = false;//
5 public synchronized void take() throws InterruptedException {
6 while(taken) {
7 // ,
8 wait();
9 }
10 // , , taken true
11 taken = true;
12 }
13
14 public synchronized void drop() {
15 // taken false,
16 taken = false;
17 notifyAll();
18 }
19 }
철학가 류:
1 package com.tyxh.ch21.c6;
2
3 import java.util.Random;
4 import java.util.concurrent.TimeUnit;
5
6 public class Philosopher implements Runnable {
7 private Chopstick left;//
8 private Chopstick right;//
9
10 private final int id;//
11 private final int ponderFactor;//
12
13 private Random rand = new Random(47);
14 private void pause() throws InterruptedException {
15 if(ponderFactor == 0) {
16 return;
17 }
18 TimeUnit.MILLISECONDS.sleep(rand.nextInt(ponderFactor *250));
19 }
20
21 public Philosopher(Chopstick left, Chopstick right, int ident, int ponder) {
22 this.left = left;
23 this.right = right;
24 this.id = ident;
25 this.ponderFactor = ponder;
26 }
27
28 public void run() {
29 try{
30 while(!Thread.interrupted()) {
31 System.out.println(this + " " + "thinking");
32 pause();
33 right.take();
34 System.out.println(this + " " + " ");
35 left.take();
36 System.out.println(this + " " + " ");
37 pause();
38 System.out.println(this + " " + " ");
39 right.drop();
40 System.out.println(this + " " + " ");
41 left.drop();
42 System.out.println(this + " " + " ");
43 }
44 }catch(InterruptedException e) {
45 System.out.println(this + " ");
46 }
47 }
48
49 public String toString() {
50 return "Phiosopher : " + id;
51 }
52 }
테스트 클래스:
1 package com.tyxh.ch21.c6;
2
3 import java.util.concurrent.ExecutorService;
4 import java.util.concurrent.Executors;
5 import java.util.concurrent.TimeUnit;
6
7 public class DeadlockingDiningPhilosophers {
8 public static void main(String[] args) throws InterruptedException {
9 int ponder = 5;
10 if(args.length > 0) {
11 ponder = Integer.parseInt(args[0]);
12 }
13 int size = 5;
14 if(args.length > 1) {
15 size = Integer.parseInt(args[1]);
16 }
17 ExecutorService exec = Executors.newCachedThreadPool();
18 Chopstick[] stick = new Chopstick[size];
19
20 for(int i = 0; i < size; i++) {
21 stick[i] = new Chopstick();
22 }
23
24 for(int i = 0; i < size; i++) {
25 Philosopher p = new Philosopher(stick[i], stick[(i+1)%size], i, ponder);
26 exec.execute(p);
27 }
28
29 TimeUnit.SECONDS.sleep(3);
30 exec.shutdownNow();
31
32 }
33 }
34
명령 행 매개 변 수 를 통 해 ponder 인자 가 철학 자의 사고 시간 을 설정 할 수도 있 고 젓가락 과 철학 자의 수량 size 를 설정 할 수도 있다.
자물쇠 가 생기 는 네 가지 필수 조건.
1 > 서로 배척 하여 사용 합 니 다. 즉, 자원 이 하나의 스 레 드 에 의 해 사용 (점유) 되 었 을 때 다른 스 레 드 는 사용 할 수 없습니다.
2 > 선점 할 수 없습니다. 자원 요구 자 는 자원 점유 자 에 게 서 자원 을 강제로 빼 앗 을 수 없고 자원 은 자원 점유 자 에 의 해 자발적으로 방출 될 수 있 습 니 다.
3 > 자원 요청 자가 다른 자원 을 요청 하 는 동시에 기 존 자원 에 대한 전 우 를 유지 하 는 것 을 요청 하고 유지 합 니 다.
4 > 순환 대기 열 이 존재 합 니 다. P1 은 P2 의 자원 을 차지 하고 P2 는 P3 의 자원 을 차지 하 며 P3 는 P1 의 자원 을 차지 합 니 다.이렇게 해서 대기 순환 도로 가 형성 되 었 다.
상술 한 네 가지 조건 이 모두 성립 될 때, 바로 자물쇠 가 형성 된다.물론 자물쇠 가 잠 긴 상태 에서 상술 한 어떤 조건 을 깨 뜨리 면 자물쇠 가 사라 질 수 있다.
책 에서 이 잠 금 을 처리 하 는 솔 루 션 (네 번 째 조건 파괴) 만 제공 합 니 다.
프로젝트 는:
앞의 철학 자가 젓가락 을 드 는 순 서 는 모두 오른쪽 을 먼저 들 고 왼쪽 을 가 지 는 것 이지 만 마지막 철학 자가 젓가락 을 드 는 순 서 는 왼쪽 을 먼저 들 고 오른쪽 을 가 지 는 것 이다. 그러면 순환 을 막 고 이 자물쇠 의 발생 을 기다 리 는 조건 을 통 해 자물쇠 의 발생 을 막 을 수 있다.
곧 코드:
1 for(int i = 0; i < size; i++) {
2 Philosopher p = new Philosopher(stick[i], stick[(i+1)%size], i, ponder);
3 exec.execute(p);
4 }
다음으로 변경:
1 for(int i = 0; i < size; i++) {
2 if(i < size - 1) {
3 Philosopher p = new Philosopher(stick[i], stick[(i+1)%size], i, ponder);
4 exec.execute(p);
5 }else {
6 Philosopher p = new Philosopher(stick[0], stick[i], i, ponder);
7 exec.execute(p);
8 }
9 }