线程练习-公司年会,前门后门进出加彩票统计

参考文章:

一、 java基础之多线程的练习题   http://blog.csdn.net/u014028392/article/details/76906801

二、Vanguard     http://www.cnblogs.com/guodong-wang/p/7226144.html


  4、某公司组织年会,会议入场时有两个入口,在入场时每位员工都能获取一张双色球彩票,假设公司有100个员工,利用多线程模拟年会入场过程,
 并分别统计每个入口入场的人数,以及每个员工拿到的彩票的号码。线程运行后打印格式如下:
 编号为: 2 的员工 从后门 入场! 拿到的双色球彩票号码是: [17, 24, 29, 30, 31, 32, 07]
 编号为: 1 的员工 从后门 入场! 拿到的双色球彩票号码是: [06, 11, 14, 22, 29, 32, 15]
 //.....
 从后门入场的员工总共: 13 位员工
 从前门入场的员工总共: 87 位员工
 
 解题思路:
   1,双色球规则:
     “双色球”彩票投注区分为红色球号码区和蓝色球号码区。
        “双色球”每注投注号码由6个红色球号码和1个蓝色球号码组成。红色球号码从1--33中选择;蓝色球号码从1--16中选择。
                       用一个数组装入这 6个红色球  和 1个蓝色球,球应该是随机产生
      2,员工入场应该是无序的,所以1-100应该乱序进入
      3,前门,后门对应两个线程,设定统计数,前门线程执行一次,统计数加一,后门也是如此
      4,线程共享代码为1,2里面的内容,最后输出一个总的统计数。

下面为代码部分:
代码1:
package homework4;

public class ThreadDemo {
	public static void main(String[] args) {
		AnnualMeeting am = new AnnualMeeting();
		Thread front = new Thread(am);
		front.setName("前门");
		Thread back = new Thread(am,"后门");
		front.start(); back.start();
	}
} 

代码2:
package homework4;

import java.util.ArrayList;
import java.util.Random;

public class Lottery {
	private static ArrayList intList = new ArrayList(); // arrList用来装双色球
	private static ArrayList strList = new ArrayList(); //用来转换彩票的输出格式
	private static Random rand = new Random();  // 用来产生红蓝球随机数
	private static int[] arrRed = new int[6]; // 6个红球
	private static int[] arrBlue = new int[1]; // 1个蓝球

	public static void getLottery() {
		intList.clear();
		strList.clear();
		for (int i = 0; i < arrRed.length;) {
			arrRed[i] = rand.nextInt(32) + 1; // 使产生的随机数在【1-33】之间
			// 产生的随机数如果已经包含,则进行下一轮循环,如果不包含,则添加进arrList中,并使i++,直到产生6个红球为止
			if (intList.contains(arrRed[i])) {
				continue;
			} else {
				intList.add(arrRed[i]);
				i++;
			}
		}

		// 产生蓝球随机数
		for (int i = 0; i < arrBlue.length;) {
			arrBlue[i] = rand.nextInt(15) + 1;  // 使产生的随机数在【1-16】之间
			if (intList.contains(arrBlue[i])) {
				continue;
			} else {
				intList.add(arrBlue[i]);
				i++;
			}
		}
//		System.out.println(intList);
		//转换彩票的输出格式 ,小于10的数组,前面加0,放到strList中,大于10的自己放进去
		for (int i = 0; i < intList.size(); i++) {
			if(intList.get(i) < 10){
				strList.add("0"+intList.get(i));
			}else {
				strList.add(""+intList.get(i));
			}
		}
		System.out.print(strList);
	}
}

代码3:

package homework4;

import java.util.ArrayList;
import java.util.Random;

public class AnnualMeeting implements Runnable {
	private int personNumber = 100; // 公司总员工数
	private int frontDoorCount = 0; // 统计前门进入人数
	private int backDoorCount = 0; // 统计后门进入人数
	private ArrayList arrayList = new ArrayList(); // 用于存储已经进入会场的员工
	private Random r = new Random();  //用来产生随机数
	private int number = 0;// 用来接收产生的随机数
	private Object obj = new Object();  //同步锁中的对象监视器
	
	public void run() {
		//不论是前门还是线程,执行起来都会进入循环,进行判断,并进行相关操作
		//FOR 循环用来控制进入的员工
	while(true) {
		//线程休眠一段时间,可以让两个线程抢着执行的更加均匀一点
		try{
			Thread.sleep(10);
		}catch(Exception ex) {
			
		}
		
		//对共享数据加上同步锁
		synchronized(obj){
			if(personNumber > 0){
					//产生一个【1-100】之间的随机数
					number = r.nextInt(100) + 1;
					//如果arrList包含了这个随机数,就相当于员工进入了会场,则跳过此轮循环,进入下一轮循环
					if (arrayList.contains(number)){
						continue;
					}else{
						arrayList.add(number);
					}	
					
					if (Thread.currentThread().getName().equals("前门")){
						frontDoorCount++;
					}else {
						if (Thread.currentThread().getName().equals("后门"))
								backDoorCount++;
					}
					System.out.print("编号为:" + number + " 的员工从 " + Thread.currentThread().getName() + " 入场!" + "拿到的双色球彩票号码是:");
					Lottery.getLottery(); // 输出彩票结果,并进行格式控制
					System.out.println();
					//上面代码执行一次,证明是一个人已经进入会场了,故personNumber--
					personNumber--;
					
				}else{
					//else的内容,也要进行线程判断,最后加上break语句,不然前后门线程会个执行一次的
					if (Thread.currentThread().getName().equals("前门")) {
						System.out.println("从前门入场的员工总共: " + frontDoorCount + " 位员工");
						break;
					}
					if (Thread.currentThread().getName().equals("后门")) {
						System.out.println("从后门入场的员工总共: " + backDoorCount + " 位员工");
						break;
					}
				}
			}		
		}
	}
}


你可能感兴趣的:(JavaSE学习)