Java 多线程练习
- 2019 年 10 月 4 日
- 筆記
题目:某公司组织年会,会议入场时有两个入口,在入场时每位员工都能获取一张双色球彩票,假设公司有100个员工,利用多线程模拟年会入场过程,
并分别统计每个入口入场的人数,以及每个员工拿到的彩票的号码。线程运行后打印格式如下:
编号为: 2 的员工 从后门 入场! 拿到的双色球彩票号码是: [17, 24, 29, 30, 31, 32, 07]
编号为: 1 的员工 从后门 入场! 拿到的双色球彩票号码是: [06, 11, 14, 22, 29, 32, 15]
//…..
从后门入场的员工总共: 13 位员工
从前门入场的员工总共: 87 位员工
分析:两个入口对应两个线程,获取彩票的方法覆写Runnable接口的run方法实现,我把这个实现了Runnable接口的类称作Paper类,里面用id字段记录员工编号,并提供get,set方法。设置第3个线程来作为随机控制100个员工进出哪个入口,因为是员工进入了入口,入口才相应彩票方法,所以我用了等待唤醒机制(这里要注意,这个等待唤醒机制必须要在同步块中,还要用同一把锁。)
代码:

class Paper implements Runnable { boolean bFlag = false; private int id; public void setId(int id) { this.id = id; } public int getId() { return this.id; } public String position; private List<String> listPosCount = new ArrayList<String>(); private HashMap<Integer, int[]> dic = new HashMap<Integer, int[]>(); private List<Integer> myList = new ArrayList<Integer>(); private int[] getNumbers(int size) { int numbers[] = new int[size]; for (int i = 0; i < size;) { boolean flag = false; numbers[i] = (int) (Math.random() * 100); for (int j = 0; j < i; j++) { if (numbers[j] == numbers[i]) { flag = true; break; } } if (flag == true) { continue; } i++; } return numbers; } @Override public void run() { synchronized (this) { while (myList.size() < 100) { while (!bFlag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.bFlag = false; if (!myList.contains(id)) { myList.add(id); if (position == "qian门" || position == "后门") listPosCount.add(position); int nums[] = getNumbers(7); dic.put(id, nums); System.out .println("编号为: " + id + " 的员工 从" + position + " 入场! 拿到的双色球彩票号码是:" + Arrays.toString(nums)); } else { } this.notifyAll(); } int a = 0, b = 0; for (String str : listPosCount) { if (str == "后门") a++; if (str == "qian门") b++; } System.out.println("从后门入场的员工总共:" + a + " 位员工"); System.out.println("从后门入场的员工总共:" + b + " 位员工"); } } }
//——————————————————————————–
//测试main函数
public class ThreadLearn2 { public static void main(String[] args) { Paper p = new Paper(); Thread th1 = new Thread(p); Thread th2 = new Thread(p); Runnable run1 = new Runnable() { @Override public void run() { synchronized (p) { List<Integer> list = new ArrayList<Integer>(); while (list.size() < 100) { int i = (int) (Math.random() * 100); if (list.indexOf(i) == -1) { p.setId(i); list.add(i); p.bFlag = true; int num = (int) (Math.random() * 100) % 2; if (num == 1) { p.position = "后门"; } else { p.position = "qian门"; } p.notifyAll(); while (p.bFlag) { try { p.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } }; Thread th3 = new Thread(run1); th1.start(); th2.start(); th3.start(); } }
