KarelWineProgram3 (KarelOOP2)

Retired DISLab
이동: 둘러보기, 찾기
/*
 * Copyright 2020 Sangwon Park @ DISLab, HUFS
 * 
 * 생산자, 소비자 프로그램이다.
 * 와인(비퍼)를 마시거나 따르려고 경쟁하는 2개의 생산자와 2개의 소비자 스레드가 있다.
 * 이때 자원을 획득하지 못하면 잠자지 않고 즉시 뒤돌아 원래의 자리로 돌아간다.
 * 
 */
package cp.java.week11.thread;
 
import java.awt.Color;
 
import hufs.dislab.karel.ColoredKarel;
import hufs.dislab.karel.IKarel;
import hufs.dislab.karel.IKarelProgram;
 
class NoWaitGlass {
	private transient boolean isFilled = false;
	private int x, y;
 
	public NoWaitGlass(int x, int y) {
		this.x = x;
		this.y = y;
	}
 
	public synchronized Color drink(IKarel karel) {
		if (!isFilled)
			return null;
		IKarelProgram program = IKarelProgram.getProgram();
		Color color = program.getCornerColor(x, y);
		program.setCornerColor(x, y, null);
		isFilled = false;
 
		return color;
	}
 
	public synchronized boolean fill(IKarel karel, Color color) {
		if (isFilled)
			return false;
		IKarelProgram program = KarelWineProgram3.getProgram();
		program.setCornerColor(x, y, color);
		isFilled = true;
		return true;
	}
}
 
class NoWaitConsumer extends ColoredKarel {
	private NoWaitGlass glass;
	private int steps;
 
	public NoWaitConsumer(NoWaitGlass glass, int steps) {
		super(null);
		this.glass = glass;
		this.steps = steps;
	}
 
	@Override
	public void run() {
		while (true) {
			setColor(null);
			move(steps);
			Color color = glass.drink(this);
			setColor(color);
			turnAround();
			move(steps);
			setColor(null);
			turnAround();
		}
	}
}
 
class NoWaitProducer extends ColoredKarel {
	private NoWaitGlass glass;
	private int steps;
	private Color color;
 
	public NoWaitProducer(Color color, NoWaitGlass glass, int steps) {
		super(color);
		this.glass = glass;
		this.steps = steps;
		this.color = color;
	}
 
 
	@Override
	public void run() {
		while (true) {
			setColor(color);
			move(steps);
			if (glass.fill(this, color))
				setColor(null);
			turnAround();
			move(steps);
			turnAround();
		}
	}
}
 
@SuppressWarnings("serial")
public class KarelWineProgram3 extends IKarelProgram {
 
	@Override
	protected void onInit() {
		int centerX = getWorldWidth() / 2;
		int centerY = getWorldHeight() / 2;
		glass = new NoWaitGlass(centerX, centerY);
 
		IKarel karel = new NoWaitConsumer(glass, STEP1);
		addIKarel(karel, centerX - 1 - STEP1, centerY, EAST, INFINITE);
		threads[0] = new Thread(karel);
 
		karel = new NoWaitProducer(RED, glass, STEP1);
		addIKarel(karel, centerX, centerY - 1 - STEP1, NORTH, INFINITE);
		threads[1] = new Thread(karel);
 
		karel = new NoWaitConsumer(glass, STEP2);
		addIKarel(karel, centerX + 1 + STEP2, centerY, WEST, INFINITE);
		threads[2] = new Thread(karel);
 
		karel = new NoWaitProducer(PINK, glass, STEP2);
		addIKarel(karel, centerX, centerY + 1 + STEP2, SOUTH, INFINITE);
		threads[3] = new Thread(karel);
	}
 
	@Override
	protected void onStart() {
		for (Thread th : threads)
			th.start();
	}
 
	public static void main(String[] args) {
		IKarelProgram.main(args, null);
	}
 
	private static final int STEP1 = 1;
	private static final int STEP2 = 2;
 
	Thread[] threads = new Thread[4];
	NoWaitGlass glass;
}
개인 도구
이름공간
변수
행위
둘러보기
구성원
연구
연구실
기타
도구모음
인쇄/내보내기