고전 자물쇠 사례 - 철학가 식사

3520 단어
사라진 자물쇠의 고전 사례: 철학가의 식사.
이 사례는 사라진 자물쇠를 초래할 수 있다.
이라는 책의 사례를 수정하여 실험을 하면 코드가 이해하기 쉽고 결과도 상대적으로 제어하기 쉽다.
첨부 코드:
젓가락 종류:
package com.tyxh.ch21.c6;

public class Chopstick {
	private boolean taken = false;//           
	public synchronized void take() throws InterruptedException {
		while(taken) {
			//      ,   
			wait();
		}
		//       ,      ,   taken true
		taken = true;
	}
	
	public synchronized void drop() {
		//        taken false,       
		taken = false;
		notifyAll();
	}
}

철학자 클래스:
package com.tyxh.ch21.c6;

import java.util.Random;
import java.util.concurrent.TimeUnit;

public class Philosopher implements Runnable {
	private Chopstick left;//   
	private Chopstick right;//   
	
	private final int id;//     
	private final int ponderFactor;//            
	
	private Random rand = new Random(47);
	private void pause() throws InterruptedException {
		if(ponderFactor == 0) {
			return;
		}
		TimeUnit.MILLISECONDS.sleep(rand.nextInt(ponderFactor *250));
	}
	
	public Philosopher(Chopstick left, Chopstick right, int ident, int ponder) {
		this.left = left;
		this.right = right;
		this.id = ident;
		this.ponderFactor = ponder;
	}
	
	public void run() {
		try{
			while(!Thread.interrupted()) {
				System.out.println(this + " " + "thinking");
				pause();
				right.take();
				System.out.println(this + " " + "    ");
				left.take();
				System.out.println(this + " " + "    ");
				pause();
				System.out.println(this + " " + " ");
				right.drop();
				System.out.println(this + " " + "     ");
				left.drop();
				System.out.println(this + " " + "     ");
			}
		}catch(InterruptedException e) {
			System.out.println(this + "      ");
		}
	}
	
	public String toString() {
		return "Phiosopher : " + id; 
 	}
}

테스트 클래스:
package com.tyxh.ch21.c6;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class DeadlockingDiningPhilosophers {
	public static void main(String[] args) throws InterruptedException {
		int ponder = 5;
		if(args.length > 0) {
			ponder = Integer.parseInt(args[0]);
		}
		int size = 5;
		if(args.length > 1) {
			size = Integer.parseInt(args[1]);
		}
		ExecutorService exec = Executors.newCachedThreadPool();
		Chopstick[] stick = new Chopstick[size];
		
		for(int i = 0; i < size; i++) {
			stick[i] = new Chopstick();
		}
		
		for(int i = 0; i < size; i++) {
			Philosopher p = new Philosopher(stick[i], stick[(i+1)%size], i, ponder);
			exec.execute(p);
		}
		
		TimeUnit.SECONDS.sleep(3);
		exec.shutdownNow();
		
	}
}
 

명령행 파라미터를 통해 Ponder 인자를 조정하여 철학자의 사고 시간을 설정할 수도 있고 젓가락과 철학자의 수량size를 설정할 수도 있다.
이 슬라이드에서는 이 잠금 장치 해결 방법만 설명합니다.
시나리오:
앞에 있는 철학자가 젓가락을 잡는 순서는 모두 오른쪽을 먼저 잡고 왼쪽을 잡는 것이지만 마지막 철학자가 젓가락을 잡는 순서는 왼쪽을 먼저 잡고 오른쪽을 들면 순환을 막고 이 자물쇠를 기다리는 조건을 통해 자물쇠가 생기는 것을 막을 수 있다.
코드 예상:
		for(int i = 0; i < size; i++) {
			Philosopher p = new Philosopher(stick[i], stick[(i+1)%size], i, ponder);
			exec.execute(p);
		}

다음으로 수정:
		for(int i = 0; i < size; i++) {
			if(i < size - 1) {
				Philosopher p = new Philosopher(stick[i], stick[(i+1)%size], i, ponder);
				exec.execute(p);
			}else {
				Philosopher p = new Philosopher(stick[0], stick[i], i, ponder);
				exec.execute(p);
			}
		}

좋은 웹페이지 즐겨찾기