Java多线程抽奖

2018-09-09  本文已影响0人  xuchengsheng

习题一

有一个抽奖池,池子里面放了固定的金额
int[] prizePool = {100,200,300,400,500,600,700,800,900,1000,1100};
此时有两个抽奖箱分别为("抽奖箱1","抽奖箱2") 并且每个箱子要轮流抽奖
列(抽奖箱1->抽奖箱2->抽奖箱1->抽奖箱2)依次类推直到抽取完毕。

package com.superxu.practice;

public class ChouJiangPool {
    
    /** 抽奖箱1 */
    public String boxOne="抽奖箱1";
    /** 抽奖箱2 */
    public String boxTwo="抽奖箱2";
    /** 奖池金额 */
    public int[] prizePool = {100,200,300,400,500,600,700,800,900,1000,1100};
    /** 奖池总数 */
    public int num = prizePool.length;
    /** 已经使用过的 */
    public boolean[] usePrize=new boolean[num];
    /** 当前线程抽奖箱 */
    public String currentThreadBox=boxOne;
    
}
package com.superxu.practice;

import java.util.Random;

public class ChouJiangMain {
    
    public static void main(String[] args) {
        ChouJiangPool pool=new ChouJiangPool();
        
        /** 抽奖箱1 */
        Thread thread1 = new Thread(new ChouJiangBox(pool));
        thread1.setName(pool.boxOne);
        thread1.start();
        
        /** 抽奖箱2 */
        Thread thread2 = new Thread(new ChouJiangBox(pool));
        thread2.setName(pool.boxTwo);
        thread2.start();
    }
    
    public static class ChouJiangBox implements Runnable{
        
        ChouJiangPool pool;
        
        public ChouJiangBox(ChouJiangPool pool) {
            this.pool=pool;
        }
        
        @Override
        public void run() {
            /** 是否还有剩余奖品可以抽取 */
            while (pool.num>0) {
                synchronized (pool) {
                    /** 获取抽奖箱名称 */
                    String boxName = Thread.currentThread().getName();
                    
                    /** 查看当前线程是否是同一个 */
                    if(!pool.currentThreadBox.equals(boxName)) {
                        try {
                            /** 如果没有轮到当前抽奖箱,则进入线程等待 */
                            pool.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    
                    /** 随机从线程中抽取奖品 */
                    Random r=new Random();
                    int index = r.nextInt(pool.prizePool.length);
                    
                    /** 查看是否抽取的奖品已使用 */
                    if(!pool.usePrize[index]) {
                        /** 从池子总获取一个奖品 */
                        int prize=pool.prizePool[index];
                        /** 奖品数量减一 */
                        pool.num-=1;
                        /** 标记已经使用的奖品 */
                        pool.usePrize[index]=true;
                        
                        /** 切换下一个抽奖箱 */
                        if(boxName.equals(pool.boxOne)) {
                            pool.currentThreadBox=pool.boxTwo;
                        }else if(boxName.equals(pool.boxTwo)){
                            pool.currentThreadBox=pool.boxOne;
                        }
                        
                        System.out.println(Thread.currentThread().getName()+"获得奖品"+prize);
                        
                        /** 通知下个抽奖箱抽奖 */
                        pool.notifyAll();
                    }
                }
            }
        }
    }
}

wait:使持有该对象的线程把该对象的控制权交出去,然后处于等待状态
notify:通知某个正在等待这个对象的控制权的线程可以继续运行
notifyAll: 会通知所有等待这个对象控制权的线程继续运行

QQ截图20180909141001.png
上一篇下一篇

猜你喜欢

热点阅读