Java多线程实操之模拟扑克抓牌

该版本简单使用了sychronized关键字来保证线程安全,后面会有其他方法实现,持续关注!

/**
 * @author manxingfu
 * @date 2023/5/26 15:53
 * @desc
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class PokerGame {

    private static final int PLAYER_COUNT = 4;
    static final List<String> poker = new ArrayList<>();

    private static final Random random = new Random();

    static {
        // 定义一副扑克牌
        String[] colors = {"黑桃", "红桃", "梅花", "方块"};
        String[] numbers = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
        for (String color : colors) {
            for (String number : numbers) {
                poker.add(color + number);
            }
        }
        // 加入大小王之后,数量到达54张,四位玩家不能平分
        /*poker.add("小王");
        poker.add("大王");*/
    }

    public static void main(String[] args) {
        // 洗牌
        Collections.shuffle(poker);

        // 创建四个线程,分别代表四个玩家
        List<Player> players = new ArrayList<>();
        for (int i = 0; i < PLAYER_COUNT; i++) {
            Player player = new Player("玩家" + (i + 1));
            players.add(player);
            // 启动线程,模拟玩家抓牌
            Thread thread = new Thread(player);
            thread.start();
            try {
                thread.join();  // 主线程等待所有子线程执行结束后进行,在继续执行
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        // 输出玩家抓到的牌
        for (Player player : players) {
            System.out.println(player);
        }
    }

    static class Player implements Runnable {

        private final String name;

        private final List<String> cards = new ArrayList<>();

        Player(String name) {
            this.name = name;
        }
        
        @Override
        public void run() {
            while (poker.size() > 0 && cards.size() < 13) {
                synchronized (poker) {
                    if (poker.size() > 0) {
                        String card = poker.remove(random.nextInt(poker.size()));
                        this.cards.add(card);
                        // System.out.printf("%s 抓到了 %s%n", name, card);
                    }
                }
            }
        }

        @Override
        public String toString() {
            return name + "抓到的牌:" + cards + " 共:" + cards.size() +"张";
        }
    }
}

输出结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值