多线程编程之卫生间

如大家所知,火车上车厢的卫生间很小,每次只能容纳一个人,一个车厢只有一个卫生间,这个卫生间会被多个人同时使用,在实际使用时,当一个人进入卫生间时则会把卫生间锁上,等出来时打开门,下一个人进去把门锁上,如果有一个人在卫生间内部则别人的人发现门是锁的则只能在外面等待。

问题分析:首先问题中有两个实体,一个是人,一个是厕所,所以设计程序时就可以设计两个类。人是多数的,厕所只有一个(暂且模拟的是一个车厢)。人的行为是随机不定的,即随时可能要上厕所。从这里就可以看出设计类时,人要设计成线程类,这样才可以体现其行为随机不定,即可能并发的一起上厕所。

 

Java实现过程如下:

 package thread.washroom;
/**
 * 厕所、卫生间(这里描述的是火车上的厕所,每次只能供一人使用)
 * @author zhoufy
 */
public class Toilet {
	/**
	 * 厕所使用中
	 */
	public synchronized void useing(User user){
		System.out.println("有人进入厕所,使用者["+user.getUserInfo()+"]");
		try {
			Thread.sleep(100); //模拟厕所使用的平均时间
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(user.getUsername()+"离开厕所......");
	}
}

 

  

package thread.washroom;

import org.apache.commons.lang.math.RandomUtils;

public class User implements Runnable{

	/**自身属性**/
	private String username;  //用户名
	private String sex;       //性别
	private int age;       //年龄
	
	/**附加属性**/
	private Toilet outToilet;
	
	/**
	 * 构造子函数 (相当人出生的时候,自身属性就开始有了)
	 */
	public User(String username, String sex, int age){
		this.username = username;
		this.sex = sex;
		this.age = age;
	}
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	
	public String getUserInfo(){
		return "姓名:"+username+", 性别:"+sex+", 年龄:"+age;
	}
	
	public void tell(Toilet t){
		outToilet = t;
	}
	
	@Override
	public void run() {
		try {
			Thread.sleep(RandomUtils.nextInt(100));
			if(outToilet!=null){ //找到了厕所
				outToilet.useing(this); //拉便便,要使用厕所
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

 

 

package thread.washroom;

public class Main {

	public static void main(String[] args){
		
		/**人是多数的,且行为不定,随时可能上厕所**/
		User user1 = new User("张三", "男", 22);
		User user2 = new User("小丽", "女", 26);
		User user3 = new User("周小舰", "男", 25);
		
		/**厕所只有1个,每次只能供1人使用**/
		Toilet t = new Toilet();
		
		user1.tell(t); //张三知道了厕所在哪
		user2.tell(t); //小丽知道了厕所在哪
		user3.tell(t); //周小舰知道了厕所在哪
		
		new Thread(user1).start();
		new Thread(user2).start();
		new Thread(user3).start();
		
	}
	
}

 

 

运行结果:

有人进入厕所,使用者[姓名:小丽, 性别:女, 年龄:26]

小丽离开厕所......

有人进入厕所,使用者[姓名:张三, 性别:男, 年龄:22]

张三离开厕所......

有人进入厕所,使用者[姓名:周小舰, 性别:男, 年龄:25]

周小舰离开厕所......

 

 

 

说明:

代码中使用synchronized关键字将厕所这个临界资源锁定,当结束时,释放锁定,从而实现了排序上厕所的结果。

 

试想如果去掉synchronized关键字,结果是什么呢?

 

运行结果:

有人进入厕所,使用者[姓名:周小舰, 性别:男, 年龄:25]

有人进入厕所,使用者[姓名:小丽, 性别:女, 年龄:26]

有人进入厕所,使用者[姓名:张三, 性别:男, 年龄:22]

周小舰离开厕所......

小丽离开厕所......

张三离开厕所......

 

场面太美,我也是醉了……

 

 

 

 

参考资料:

http://www.cnblogs.com/springcsc/archive/2009/12/03/1616394.html

 

 

Java实现过程如下:

 package thread.washroom;
/**
 * 厕所、卫生间(这里描述的是火车上的厕所,每次只能供一人使用)
 * @author zhoufy
 */
public class Toilet {
	/**
	 * 厕所使用中
	 */
	public synchronized void useing(User user){
		System.out.println("有人进入厕所,使用者["+user.getUserInfo()+"]");
		try {
			Thread.sleep(100); //模拟厕所使用的平均时间
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(user.getUsername()+"离开厕所......");
	}
}

 

  

package thread.washroom;

import org.apache.commons.lang.math.RandomUtils;

public class User implements Runnable{

	/**自身属性**/
	private String username;  //用户名
	private String sex;       //性别
	private int age;       //年龄
	
	/**附加属性**/
	private Toilet outToilet;
	
	/**
	 * 构造子函数 (相当人出生的时候,自身属性就开始有了)
	 */
	public User(String username, String sex, int age){
		this.username = username;
		this.sex = sex;
		this.age = age;
	}
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	
	public String getUserInfo(){
		return "姓名:"+username+", 性别:"+sex+", 年龄:"+age;
	}
	
	public void tell(Toilet t){
		outToilet = t;
	}
	
	@Override
	public void run() {
		try {
			Thread.sleep(RandomUtils.nextInt(100));
			if(outToilet!=null){ //找到了厕所
				outToilet.useing(this); //拉便便,要使用厕所
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

 

 

package thread.washroom;

public class Main {

	public static void main(String[] args){
		
		/**人是多数的,且行为不定,随时可能上厕所**/
		User user1 = new User("张三", "男", 22);
		User user2 = new User("小丽", "女", 26);
		User user3 = new User("周小舰", "男", 25);
		
		/**厕所只有1个,每次只能供1人使用**/
		Toilet t = new Toilet();
		
		user1.tell(t); //张三知道了厕所在哪
		user2.tell(t); //小丽知道了厕所在哪
		user3.tell(t); //周小舰知道了厕所在哪
		
		new Thread(user1).start();
		new Thread(user2).start();
		new Thread(user3).start();
		
	}
	
}

 

 

运行结果:

有人进入厕所,使用者[姓名:小丽, 性别:女, 年龄:26]

小丽离开厕所......

有人进入厕所,使用者[姓名:张三, 性别:男, 年龄:22]

张三离开厕所......

有人进入厕所,使用者[姓名:周小舰, 性别:男, 年龄:25]

周小舰离开厕所......

 

 

 

说明:

代码中使用synchronized关键字将厕所这个临界资源锁定,当结束时,释放锁定,从而实现了排序上厕所的结果。

 

试想如果去掉synchronized关键字,结果是什么呢?

 

运行结果:

有人进入厕所,使用者[姓名:周小舰, 性别:男, 年龄:25]

有人进入厕所,使用者[姓名:小丽, 性别:女, 年龄:26]

有人进入厕所,使用者[姓名:张三, 性别:男, 年龄:22]

周小舰离开厕所......

小丽离开厕所......

张三离开厕所......

 

场面太美,我也是醉了……

 

 

 

 

参考资料:

http://www.cnblogs.com/springcsc/archive/2009/12/03/1616394.html

 

猜你喜欢

转载自15838341661-139-com.iteye.com/blog/2223374