這是鍛鍊的要求:我需要實現與同步方法的Java程序,但我不能避免死鎖
- 有3個房間S1,S2,S3,最大容量20,15,10
- N多人都試圖在房間進入,如果房間都充滿等待
在第一次訪問的每個人試圖在S1進入和等待,如果它的
全時一個人參觀了房間可以進入一個又一個,寧願一個不完整的房間,並沒有到過的房間
- 一個人可以從一個房間不會退出,除非有其他可用的房間
- 時訪問過的每個房間一個人結束訪華並打印訪問序列
- 每個人在1秒5秒之前等待,然後嘗試更換房間
- 每個房間的人數必須打印到所有訪問結束時。
在Java中使用同步方法。
這是我的代碼:
package com.company;
public class Main {
public static void main(String[] args) throws InterruptedException {
final int N = 30; //people number (valore da cambiare anche all'attributo statico countPerson della classe Person)
Guide guide = new Guide();
Person [] persons = new Person[N];
System.out.println("Starting visit");
for(int i = 0; i<N; i++){
persons[i] = new Person(i, guide);
persons[i].start();
}
while(Person.countPerson!=0) {
try {
Thread.sleep(1000);
System.out.println(" ");
for (int i=1; i<4; i++){
System.out.print("There are "+ guide.countPeople(i)+" people in room number "+i+" ------");
}
}catch (InterruptedException e){
System.out.println("Thread main interrupted");
}
}
}
}
class Guide{
private int S1=20;
private int S2=15;
private int S3=10;
public synchronized int enterS1() throws InterruptedException{
while (S1==0)
wait();
S1--;
notifyAll();
return 1;
}
public synchronized int enterS2() throws InterruptedException{
while (S2==0)
wait();
S2--;
notifyAll();
return 2;
}
public synchronized int enterS3() throws InterruptedException{
while (S3==0)
wait();
S3--;
notifyAll();
return 3;
}
public synchronized void exitRoom(int actualRoom){
switch (actualRoom){
case 1:{
S1++;
notifyAll();
break;
}
case 2:{
S2++;
notifyAll();
break;
}
case 3:{
S3++;
notifyAll();
break;
}
}
}
public int status(int room){
switch (room){
case 1:{
return S1;
}
case 2:{
return S2;
}
case 3:{
return S3;
}
default:{
return 999;
}
}
}
public int countPeople(int room){
switch (room){
case 1:{
return 20-S1;
}
case 2:{
return 15-S2;
}
case 3:{
return 10-S3;
}
default:{
return 999;
}
}
}
}
class Person extends Thread{
private int id;
private Guide guide;
private boolean[] visited;
private int[] order;
private int actualRoom;
private boolean isFirstAccess;
private boolean visitTerminated;
private int counterOrder;
public static int countPerson=30;
public Person(int id, Guide guide) {
this.id = id;
this.guide = guide;
this.visited = new boolean[3];
this.order = new int[3];
this.actualRoom = 0;
this.isFirstAccess=true;
this.visitTerminated = false;
this.counterOrder=0;
for (int i = 0; i < 3; i++) {
visited[i] = false;
order[i] = 0;
}
}
@Override
public void run() {
while (!visitTerminated){
try {
//start first access for this person
while(isFirstAccess){
if(guide.status(1)!=0) {
actualRoom = guide.enterS1();
if (actualRoom == 1) {
isFirstAccess = false;
visited[0] = true;
order[counterOrder]=1;
counterOrder++;
Thread.sleep((int)(Math.random()*4001)+1000);
}
}
else {
Thread.sleep((int)(Math.random()*4001)+1000);
}
}
//end first access for this person
if(guide.status(2)!=0 /*&& actualRoom!=2 */&& !visited[1]){
guide.exitRoom(actualRoom);
actualRoom=guide.enterS2();
visited[1]=true;
order[counterOrder]=2;
counterOrder++;
Thread.sleep((int)(Math.random()*4001)+1000);
} else if (guide.status(3)!=0 /*&& actualRoom!=3*/&& !visited[2]){
guide.exitRoom(actualRoom);
actualRoom=guide.enterS3();
visited[2]=true;
order[counterOrder]=3;
counterOrder++;
Thread.sleep((int)(Math.random()*4001)+1000);
} else if(guide.status(1)!=0 /*&& actualRoom!=1*/){
guide.exitRoom(actualRoom);
actualRoom = guide.enterS1();
Thread.sleep((int)(Math.random()*4001)+1000);
}else if(guide.status(2)!=0 /*&& actualRoom!=2*/){
guide.exitRoom(actualRoom);
actualRoom=guide.enterS2();
if(!visited[1]){
visited[1]=true;
order[counterOrder]=2;
counterOrder++;
}
Thread.sleep((int)(Math.random()*4001)+1000);
} else if (guide.status(3)!=0 /*&& actualRoom!=3*/){
guide.exitRoom(actualRoom);
actualRoom=guide.enterS3();
if(!visited[2]){
visited[2]=true;
order[counterOrder]=3;
counterOrder++;
}
Thread.sleep((int)(Math.random()*4001)+1000);
}
if(visited[0] && visited[1] && visited[2]){
guide.exitRoom(actualRoom);
System.out.println("Person number "+this.id+" has terminated his visit. "+"Visiting order: "+order[0]+"-"+order[1]+"-"+order[2]);
visitTerminated=true;
}
}catch (InterruptedException e){
System.out.println("Thread interrupted, people are leaving rooms ");
guide.exitRoom(actualRoom);
}
}
countPerson--;
}
}
如果N> 50我的程序死鎖進入,我不能修復它。你可以幫幫我嗎? 謝謝
這個問題是更多的代碼審查的事情。他們可以給你一些有用的指針。這整個代碼都需要重建。特別是關於線程使用。 – Tschallacka