Skip to content

Instantly share code, notes, and snippets.

@sftblw
Last active November 21, 2017 11:13
Show Gist options
  • Save sftblw/0e60bd93dbe388a86e1b5a2a65328868 to your computer and use it in GitHub Desktop.
Save sftblw/0e60bd93dbe388a86e1b5a2a65328868 to your computer and use it in GitHub Desktop.
쳐먹는_철학자.java

쳐먹는 철학자

  • 식사하는 철학자 문제의 풀이 중 하나입니다.
  • 젓가락 두 개를 다 잡지 못 하면 바로 놓는 바보같은 방법으로 해결하였습니다. 일단 대충 해결
  • 언젠가 추후에 공부하여 수정해야겠죠.
  • Java로 한글코딩을 했군요.
package 쳐먹는_철학자;
import java.util.logging.Level;
import java.util.logging.Logger;
public class 메인클래스 {
public static void main(String[] args) {
new 원탁().만찬();
}
}
class 젓가락 {
int 젓가락_번호;
public 젓가락(int 젓가락_번호) {
this.젓가락_번호 = 젓가락_번호;
}
}
class 철학자 extends Thread {
젓가락 왼손 = null;
젓가락 오른손 = null;
원탁 책상 = null;
int 철학자_번호;
int 식사_횟수 = 0;
boolean 식사중 = false;
public boolean 왼손_먼저 = true;
private String 탭() {
StringBuffer bf = new StringBuffer();
for (int i = 0; i < 철학자_번호; i++) {
bf.append("\t");
}
return bf.toString();
}
public 철학자(int 철학자_번호, 원탁 책상) {
this.철학자_번호 = 철학자_번호;
this.책상 = 책상;
}
public boolean 젓가락_들기(boolean 왼손여부) {
if (왼손여부 && 왼손 != null) return true;
if (!왼손여부 && 오른손 != null) return true;
젓가락 ㅈㄱㄹ = 책상.젓가락_주기(왼손여부 ? 철학자_번호 : (철학자_번호 + 1) % 책상.좌석갯수);
if (ㅈㄱㄹ == null) {
return false;
}
else {
if (왼손여부) 왼손 = ㅈㄱㄹ;
else 오른손 = ㅈㄱㄹ;
log(탭() + "철학자[" + 철학자_번호 + "]: 젓가락 들음 ↗: " + (왼손여부 ? "왼손" : "오른손"));
return true;
}
}
public boolean 식사() {
if ((왼손 == null) || (오른손 == null)) {
return false;
} else {
try {
long waittime = (long) (Math.random()*10 + 10);
식사중 = true;
log("철학자[" + 철학자_번호 + "]: 식사 시작 : " + waittime + "ms동안");
sleep(waittime);
식사중 = false;
log(탭() + "철학자[" + 철학자_번호 + "]: 식사 끝");
식사_횟수++;
return true;
} catch (InterruptedException ex) {
Logger.getLogger(철학자.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
}
}
public void 젓가락_내려놓기() {
if (오른손 != null) {
책상.젓가락_놓기(오른손);
오른손 = null;
log(탭() + "철학자[" + 철학자_번호 + "]: 젓가락 내려놓음↘: " + "오른손");
}
if (왼손 != null) {
책상.젓가락_놓기(왼손);
왼손 = null;
log(탭() + "철학자[" + 철학자_번호 + "]: 젓가락 내려놓음↘: " + "왼손");
}
}
@Override
public void run() {
synchronized(this) {
for (int i = 0; i < 9; i++) {
do {
if (!젓가락_들기(왼손_먼저)) {
notifyAll();
yield();
}
else if(!젓가락_들기(!왼손_먼저)) {
// 젓가락_내려놓기();
notifyAll();
yield();
}
notifyAll();
yield();
if (식사()) {
젓가락_내려놓기();
notifyAll();
yield();
break;
}
} while(true);
}
}
젓가락_내려놓기();
}
@Override
public String toString() {
return "[" + (왼손 != null ? "|" : " ") + "_" + (식사중 ? "*" : 식사_횟수) + "_" + (오른손 != null ? "|" : " ") + "]";
}
private void log(String str) {
synchronized(System.out) {
System.out.println(str);
System.out.println(책상.toString());
}
}
}
class 원탁 {
// 철학자 0은 젓가락 0, 1을 들 수 있음
젓가락[] 젓가락슬롯;
철학자[] 철학자슬롯;
int 좌석갯수 = 5;
public 원탁() {
젓가락슬롯 = new 젓가락[좌석갯수];
철학자슬롯 = new 철학자[좌석갯수];
for(int i = 0; i < 좌석갯수; i++) {
젓가락슬롯[i] = new 젓가락(i);
철학자슬롯[i] = new 철학자(i, this);
}
철학자슬롯[0].왼손_먼저 = false;
}
public synchronized 젓가락 젓가락_주기(int 젓가락번호) {
if (젓가락슬롯[젓가락번호] != null) {
젓가락 ㅈㄱㄹ = 젓가락슬롯[젓가락번호];
젓가락슬롯[젓가락번호] = null;
return ㅈㄱㄹ;
} else {
return null;
}
}
public synchronized boolean 젓가락_놓기(젓가락 ㅈ) {
if (젓가락슬롯[ㅈ.젓가락_번호] == null) {
젓가락슬롯[ㅈ.젓가락_번호] = ㅈ;
return true;
} else {
return false;
}
}
public void 만찬() {
for(int i = 0; i < 좌석갯수; i++) {
철학자슬롯[i].start();
}
for(철학자 ㅊ : 철학자슬롯) {
try {
ㅊ.join();
} catch (InterruptedException ex) {
Logger.getLogger(원탁.class.getName()).log(Level.SEVERE, null, ex);
}
}
System.out.println(this.toString());
}
@Override
public String toString() {
StringBuffer bf = new StringBuffer();
bf.append(젓가락슬롯[0] != null ? " 젓 " : " 없 ");
for (int i = 0; i < 좌석갯수; i++) {
bf.append(철학자슬롯[i].toString() + (젓가락슬롯[(i+1) % 좌석갯수] != null ? " 젓 " : " 없 "));
}
return bf.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment