Java的面包房算法模拟银行排队取号的问题

evilsbei 2014-10-29 10:59:45
就是类似那个银行的业务排号系统,正常情况应该是从四个线程各自取号,但是四个线程取出来的都是1,后面的号都取不出来,不知道问题出在哪里。。。求大神指教。。。


代码:

CS.java

import java.util.concurrent.atomic.AtomicIntegerArray;


public class CS extends Thread{
private int id;


AtomicIntegerArray ticket ;
AtomicIntegerArray entering ;

public CS(int id){
this.id = id;
ticket = new AtomicIntegerArray(id);
entering = new AtomicIntegerArray(id);

for(int i = 0; i < id; ++i)
{
ticket.set(i, 0);
entering.set(i, 0);
}
}

public void run(){
while(true){
critical_section();
}
}

public void critical_section(){


for(int i = 0; i < id; i++)
{
entering.set(i, 1);

ticket.set(i, max(ticket) + 1);

entering.set(i, 0);
for(int j = 0; j < ticket.length(); ++j)
{
if(j != i)
{
while(entering.get(i) != 0){}
while(ticket.get(j) != 0 && (ticket.get(j) < ticket.get(i) || (ticket.get(j) == ticket.get(i) && j < i))){}
}
}
System.out.println("Process : " + this.id + " is in its critical section" + "get ticket: " + ticket.get(i) + " ticket length: " + ticket.length() );
unlock(i);
}

try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public void unlock(int i){
ticket.set(i, 0);
non_critical_section();
}

public void non_critical_section(){

System.out.println("Process : " + this.id + " is in its non-critical section");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private int max(AtomicIntegerArray turn2) {
// TODO Auto-generated method stub
int max = turn2.get(0);
for(int i = 0; i < this.id; i++){
if(turn2.get(i) > max)
{
max = turn2.get(i);
}
}
return max;
}


}



GreatBakeOff.java

public class GreatBakeOff {

public static void main(String[] args) {
int processes = 4;
CS[] cs = new CS[processes];
for(int i = 0; i < processes; i++){
cs[i] = new CS(i);
}

for(int i = 0; i < processes; i++){
cs[i].start();
}
}
}


输出结果:


...全文
299 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Mr_JieLQ 2014-10-30
  • 打赏
  • 举报
回复
引用 6 楼 evilsbei 的回复:
碉堡了~牛逼~ 非常感谢~ 能加你个好友不~ [quote=引用 5 楼 u011564172 的回复:] 这回应该可以了

import java.util.concurrent.atomic.AtomicIntegerArray;

public class CS extends Thread {
	private int id;

	static AtomicIntegerArray entering = new AtomicIntegerArray(4);;
	static AtomicIntegerArray ticket = new AtomicIntegerArray(4);

	public CS(int id) {
		this.id = id;
	}

	public void run() {
		while (true) {
			critical_section(id);
		}
	}

	public void critical_section(int i) {
			entering.set(i, 1);
			ticket.set(i, max(ticket) + 1);
			entering.set(i, 0);
			for (int j = 0; j < ticket.length(); ++j) {
				if (j != i) {
					while (entering.get(i) != 0) {
						
					}
					while (ticket.get(j) != 0
							&& (ticket.get(j) < ticket.get(i) || (ticket.get(j) == ticket
									.get(i) && j < i))) {
					}
				}
			}
			System.out.println("Process : " + this.id
					+ " is in its critical section" + "get ticket: "
					+ ticket.get(i) + " ticket length: " + ticket.length());
			
		try {	
			unlock(i);
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void unlock(int i) {
		ticket.set(i, 0);
		non_critical_section();
	}

	public void non_critical_section() {

		System.out.println("Process : " + this.id
				+ " is in its non-critical section");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private int max(AtomicIntegerArray turn2) {
		// TODO Auto-generated method stub
		int max = turn2.get(0);
		for (int i = 0; i < this.id; i++) {
			if (turn2.get(i) > max) {
				max = turn2.get(i);
			}
		}
		return max;
	}

}


public class GreatBakeOff {
	public static void main(String[] args) {
		int processes = 4;
		CS[] cs = new CS[processes];
		for(int i = 0; i < processes; i++){
			cs[i] = new CS(i);
		}

		for(int i = 0; i < processes; i++){
			new Thread(cs[i]).start();
		}
	}
}
[/quote] 可以啊,另外,别忘了结贴
evilsbei 2014-10-30
  • 打赏
  • 举报
回复
碉堡了~牛逼~ 非常感谢~ 能加你个好友不~
引用 5 楼 u011564172 的回复:
这回应该可以了

import java.util.concurrent.atomic.AtomicIntegerArray;

public class CS extends Thread {
	private int id;

	static AtomicIntegerArray entering = new AtomicIntegerArray(4);;
	static AtomicIntegerArray ticket = new AtomicIntegerArray(4);

	public CS(int id) {
		this.id = id;
	}

	public void run() {
		while (true) {
			critical_section(id);
		}
	}

	public void critical_section(int i) {
			entering.set(i, 1);
			ticket.set(i, max(ticket) + 1);
			entering.set(i, 0);
			for (int j = 0; j < ticket.length(); ++j) {
				if (j != i) {
					while (entering.get(i) != 0) {
						
					}
					while (ticket.get(j) != 0
							&& (ticket.get(j) < ticket.get(i) || (ticket.get(j) == ticket
									.get(i) && j < i))) {
					}
				}
			}
			System.out.println("Process : " + this.id
					+ " is in its critical section" + "get ticket: "
					+ ticket.get(i) + " ticket length: " + ticket.length());
			
		try {	
			unlock(i);
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void unlock(int i) {
		ticket.set(i, 0);
		non_critical_section();
	}

	public void non_critical_section() {

		System.out.println("Process : " + this.id
				+ " is in its non-critical section");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private int max(AtomicIntegerArray turn2) {
		// TODO Auto-generated method stub
		int max = turn2.get(0);
		for (int i = 0; i < this.id; i++) {
			if (turn2.get(i) > max) {
				max = turn2.get(i);
			}
		}
		return max;
	}

}


public class GreatBakeOff {
	public static void main(String[] args) {
		int processes = 4;
		CS[] cs = new CS[processes];
		for(int i = 0; i < processes; i++){
			cs[i] = new CS(i);
		}

		for(int i = 0; i < processes; i++){
			new Thread(cs[i]).start();
		}
	}
}
evilsbei 2014-10-29
  • 打赏
  • 举报
回复
非常非常感谢u011564172,但是本地显示的结果不对,我想要的是那四个线程每次取号,取出来的都是递增的。 你改的这个调试之后我发现,是每四个线程才会递增一次。
引用 1 楼 u011564172 的回复:
我修改了,请在本地再测试,看看是不是你想要的结果

import java.util.concurrent.atomic.AtomicIntegerArray;

public class CS extends Thread {
	private int id;

	AtomicIntegerArray ticket;
	AtomicIntegerArray entering;

	public CS(int id) {
		this.id = id;
		ticket = new AtomicIntegerArray(id);
		entering = new AtomicIntegerArray(id);

		for (int i = 0; i < id; ++i) {
			ticket.set(i, 0);
			entering.set(i, 0);
		}
	}

	public void run() {
		while (true) {
			critical_section();
		}
	}

	public void critical_section() {

		for (int i = 0; i < id; i++) {
			entering.set(i, i);

			ticket.set(i, max(entering) + 1);

			entering.set(i, 0);
			for (int j = 0; j < ticket.length(); ++j) {
				if (j != i) {
					while (entering.get(i) != 0) {
					}
					while (ticket.get(j) != 0
							&& (ticket.get(j) < ticket.get(i) || (ticket.get(j) == ticket
									.get(i) && j < i))) {
					}
				}
			}
			System.out.println("Process : " + this.id
					+ " is in its critical section" + "get ticket: "
					+ ticket.get(i) + " ticket length: " + ticket.length());
			unlock(i);
		}

		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void unlock(int i) {
		ticket.set(i, 0);
		non_critical_section();
	}

	public void non_critical_section() {

		System.out.println("Process : " + this.id
				+ " is in its non-critical section");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private int max(AtomicIntegerArray turn2) {
		// TODO Auto-generated method stub
		int max = turn2.get(0);
		for (int i = 0; i < this.id; i++) {
			if (turn2.get(i) > max) {
				max = turn2.get(i);
			}
		}
		return max;
	}

}
Mr_JieLQ 2014-10-29
  • 打赏
  • 举报
回复
我修改了,请在本地再测试,看看是不是你想要的结果

import java.util.concurrent.atomic.AtomicIntegerArray;

public class CS extends Thread {
	private int id;

	AtomicIntegerArray ticket;
	AtomicIntegerArray entering;

	public CS(int id) {
		this.id = id;
		ticket = new AtomicIntegerArray(id);
		entering = new AtomicIntegerArray(id);

		for (int i = 0; i < id; ++i) {
			ticket.set(i, 0);
			entering.set(i, 0);
		}
	}

	public void run() {
		while (true) {
			critical_section();
		}
	}

	public void critical_section() {

		for (int i = 0; i < id; i++) {
			entering.set(i, i);

			ticket.set(i, max(entering) + 1);

			entering.set(i, 0);
			for (int j = 0; j < ticket.length(); ++j) {
				if (j != i) {
					while (entering.get(i) != 0) {
					}
					while (ticket.get(j) != 0
							&& (ticket.get(j) < ticket.get(i) || (ticket.get(j) == ticket
									.get(i) && j < i))) {
					}
				}
			}
			System.out.println("Process : " + this.id
					+ " is in its critical section" + "get ticket: "
					+ ticket.get(i) + " ticket length: " + ticket.length());
			unlock(i);
		}

		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void unlock(int i) {
		ticket.set(i, 0);
		non_critical_section();
	}

	public void non_critical_section() {

		System.out.println("Process : " + this.id
				+ " is in its non-critical section");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private int max(AtomicIntegerArray turn2) {
		// TODO Auto-generated method stub
		int max = turn2.get(0);
		for (int i = 0; i < this.id; i++) {
			if (turn2.get(i) > max) {
				max = turn2.get(i);
			}
		}
		return max;
	}

}
Mr_JieLQ 2014-10-29
  • 打赏
  • 举报
回复
这回应该可以了

import java.util.concurrent.atomic.AtomicIntegerArray;

public class CS extends Thread {
	private int id;

	static AtomicIntegerArray entering = new AtomicIntegerArray(4);;
	static AtomicIntegerArray ticket = new AtomicIntegerArray(4);

	public CS(int id) {
		this.id = id;
	}

	public void run() {
		while (true) {
			critical_section(id);
		}
	}

	public void critical_section(int i) {
			entering.set(i, 1);
			ticket.set(i, max(ticket) + 1);
			entering.set(i, 0);
			for (int j = 0; j < ticket.length(); ++j) {
				if (j != i) {
					while (entering.get(i) != 0) {
						
					}
					while (ticket.get(j) != 0
							&& (ticket.get(j) < ticket.get(i) || (ticket.get(j) == ticket
									.get(i) && j < i))) {
					}
				}
			}
			System.out.println("Process : " + this.id
					+ " is in its critical section" + "get ticket: "
					+ ticket.get(i) + " ticket length: " + ticket.length());
			
		try {	
			unlock(i);
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void unlock(int i) {
		ticket.set(i, 0);
		non_critical_section();
	}

	public void non_critical_section() {

		System.out.println("Process : " + this.id
				+ " is in its non-critical section");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private int max(AtomicIntegerArray turn2) {
		// TODO Auto-generated method stub
		int max = turn2.get(0);
		for (int i = 0; i < this.id; i++) {
			if (turn2.get(i) > max) {
				max = turn2.get(i);
			}
		}
		return max;
	}

}


public class GreatBakeOff {
	public static void main(String[] args) {
		int processes = 4;
		CS[] cs = new CS[processes];
		for(int i = 0; i < processes; i++){
			cs[i] = new CS(i);
		}

		for(int i = 0; i < processes; i++){
			new Thread(cs[i]).start();
		}
	}
}
evilsbei 2014-10-29
  • 打赏
  • 举报
回复
恩恩,这个我昨天出现了这个结果,但是只是一个线程的,所以我加了public void unlock(int i) { ticket.set(i, 0); non_critical_section(); 但是我想启动四个线程达到这样的结果,应该怎么去做呢。
引用 3 楼 u011564172 的回复:
你只启动一个线程看看,你写的这个就是每个线程去一个固定数组取号,不是四个线程去一个数组取号

public class GreatBakeOff {
	public static void main(String[] args) {
		CS cs = new CS(4);
		cs.start();
	}
}

Process : 4 is in its critical sectionget ticket: 1 ticket length: 4
Process : 4 is in its non-critical section
Process : 4 is in its critical sectionget ticket: 2 ticket length: 4
Process : 4 is in its non-critical section
Process : 4 is in its critical sectionget ticket: 3 ticket length: 4
Process : 4 is in its non-critical section
Process : 4 is in its critical sectionget ticket: 4 ticket length: 4
Process : 4 is in its non-critical section
Mr_JieLQ 2014-10-29
  • 打赏
  • 举报
回复
你只启动一个线程看看,你写的这个就是每个线程去一个固定数组取号,不是四个线程去一个数组取号

public class GreatBakeOff {
	public static void main(String[] args) {
		CS cs = new CS(4);
		cs.start();
	}
}

Process : 4 is in its critical sectionget ticket: 1 ticket length: 4
Process : 4 is in its non-critical section
Process : 4 is in its critical sectionget ticket: 2 ticket length: 4
Process : 4 is in its non-critical section
Process : 4 is in its critical sectionget ticket: 3 ticket length: 4
Process : 4 is in its non-critical section
Process : 4 is in its critical sectionget ticket: 4 ticket length: 4
Process : 4 is in its non-critical section

50,530

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧