1. 程式人生 > >多執行緒模擬搶紅包

多執行緒模擬搶紅包

今天有朋友問我一道面試題,有5個人搶5個紅包,可重複搶,用多執行緒程式實現,實現方式有多種,分享一下我的思路:應用了阻塞佇列的特性

/**
 * Created by zhanglinqiang on 2016/6/23.
 */
public class MyTest {

    public static void main(String[] args) throws InterruptedException {
        LinkedBlockingQueue<LuckyMoney> luckyMoneys = new LinkedBlockingQueue<>();
        List<FutureTask> futureTasks = new ArrayList<>();
        //準備搶紅包
        for (int i = 0; i < 5; i++) {
            FutureTask<Object> futureTask = new FutureTask<>(new CatchLuckMoney(luckyMoneys, "name" + i), null);
            new Thread(futureTask,"name"+i).start();
            futureTasks.add(futureTask);
        }
        Thread.sleep(5);//確保搶紅包執行緒準備就緒
        Random random = new Random(100);
        //發5個紅包
        for (int i = 0; i < 5; i++) {
            luckyMoneys.put(new LuckyMoney("紅包"+i, random.nextInt(100)+1));
        }
        //等到紅包搶完
        while (!luckyMoneys.isEmpty()){
            Thread.sleep(1);
        }
        //終止搶紅包執行緒
        for (FutureTask futureTask : futureTasks) {
            futureTask.cancel(true);
        }

    }
}

class CatchLuckMoney implements Runnable {

    public CatchLuckMoney(LinkedBlockingQueue<LuckyMoney> luckyMoneys, String name) {
        this.luckyMoneys = luckyMoneys;
        this.name = name;
    }

    private LinkedBlockingQueue<LuckyMoney> luckyMoneys;
    private String name;

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            LuckyMoney redPackage = null;
            try {
                redPackage = luckyMoneys.take();
            } catch (InterruptedException e) {
//                e.printStackTrace();
                break;
            }
            System.out.println(name + "搶到了-->" + redPackage);
            luckyMoneys.remove(redPackage);
        }
        System.out.println("end>>>>>>>>>>>>>>>>>>>>>>>>>>>>"+Thread.currentThread().getName());
    }
}

class LuckyMoney {

    public LuckyMoney(String name, Integer money) {
        this.name = name;
        this.money = money;
    }

    private String name;
    private Integer money;

    @Override
    public String toString() {
        return "LuckyMoney{" +
                "name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

執行效果:
Connected to the target VM, address: '127.0.0.1:8869', transport: 'socket'
name3搶到了-->LuckyMoney{name='紅包0', money=16}
name4搶到了-->LuckyMoney{name='紅包3', money=89}
name0搶到了-->LuckyMoney{name='紅包2', money=75}
name1搶到了-->LuckyMoney{name='紅包1', money=51}
name3搶到了-->LuckyMoney{name='紅包4', money=92}
end>>>>>>>>>>>>>>>>>>>>>>>>>>>>name0
end>>>>>>>>>>>>>>>>>>>>>>>>>>>>name4
end>>>>>>>>>>>>>>>>>>>>>>>>>>>>name3
Disconnected from the target VM, address: '127.0.0.1:8869', transport: 'socket'
end>>>>>>>>>>>>>>>>>>>>>>>>>>>>name1
end>>>>>>>>>>>>>>>>>>>>>>>>>>>>name2

Process finished with exit code 0