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; }