您的位置:首页 > 其它

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

2018-01-28 21:34 232 查看
参考文章:

一、 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<Integer> intList = new ArrayList<Integer>(); // arrList用来装双色球
private static ArrayList<String> strList = new ArrayList<String>(); //用来转换彩票的输出格式
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<Integer> arrayList = new ArrayList<Integer>(); // 用于存储已经进入会场的员工
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;
}
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: