用Java写多线程随机发扑克牌

1、Java:使用多线程,模拟将52张扑克牌随机分发给4个人,每人13张。

2、最后输出每个玩家所得的牌,牌的花色要显示出来,比如:黑桃A、红桃10、梅花J、方块K。

3、用最基础的Java语言写,尽量多注释。(我基础较差,比较难看懂)

package com.nxftl.study.question.csdn.poke;

import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author darkltl
 * @className Poke
 * @email darkltl@163.com
 * @description
 * 多线程发扑克牌
 */
@Slf4j
public class Poke {

    private static final Stack<String> POKES = new Stack<>();

    private static final String[] POKE_ARRAY = {
            " ♠A "," ♠2 "," ♠3 "," ♠4 "," ♠5 "," ♠6 "," ♠7 "," ♠8 "," ♠9 "," ♠10 "," ♠J "," ♠Q "," ♠K ",
            " ♣A "," ♣2 "," ♣3 "," ♣4 "," ♣5 "," ♣6 "," ♣7 "," ♣8 "," ♣9 "," ♣10 "," ♣J "," ♣Q "," ♣K ",
            " ♥A "," ♥2 "," ♥3 "," ♥4 "," ♥5 "," ♥6 "," ♥7 "," ♥8 "," ♥9 "," ♥10 "," ♥J "," ♥Q "," ♥K ",
            " ♦A "," ♦2 "," ♦3 "," ♦4 "," ♦5 "," ♦6 "," ♦7 "," ♦8 "," ♦9 "," ♦10 "," ♦J "," ♦Q "," ♦K "
    };

    static {
        POKES.addAll(Arrays.asList(POKE_ARRAY));
    }



    /**
     * 洗牌
     */
    private static void shuffle(){
        //简单洗牌,利用随机数交换两数位置,表示洗牌
        for (int i = 0; i < POKES.size(); i++) {
            int index = (int) ((Math.random() * 52));
            String currentElement = POKES.get(i);
            POKES.set(i,POKES.get(index));
            POKES.set(index,currentElement);
        }
    }





    public static void main(String[] args) {
        Gamer gamerOne = new Gamer("张三");
        Gamer gamerTwo = new Gamer("李四");
        Gamer gamerThree = new Gamer("王五");
        Gamer gamerFour = new Gamer("趙六");
        List<String> gamerOnePokes = gamerOne.getPokes();
        List<String> gamerTwoPokes = gamerTwo.getPokes();
        List<String> gamerThreePokes = gamerThree.getPokes();
        List<String> gamerFourPokes = gamerFour.getPokes();
        shuffle();

        Thread executor = new Thread(
                () -> {
                    //利用AtomicInteger自增 等同于i++ (只不过是线程安全的)
                    AtomicInteger index = new AtomicInteger(0);
                    //循环条件是当扑克总量-4大于等于自增下标时进入循环体(-4代表一轮)
                    while(POKES.size()-4 >= index.get()){
                        gamerOnePokes.add(POKES.get(index.getAndIncrement()));
                        gamerTwoPokes.add(POKES.get(index.getAndIncrement()));
                        gamerThreePokes.add(POKES.get(index.getAndIncrement()));
                        gamerFourPokes.add(POKES.get(index.getAndIncrement()));
                    }
                }
        );
        executor.start();

        //等待线程结束
        while(executor.isAlive()){
        }
        gamerFourPokes.forEach(
                System.out::print
        );
        System.out.println();
        gamerThreePokes.forEach(
                System.out::print
        );
        System.out.println();
        gamerTwoPokes.forEach(
                System.out::print
        );

        System.out.println();
        gamerOnePokes.forEach(
                System.out::print
        );

    }
}

class Gamer {

    private List<String> pokes = new ArrayList<>();

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    private String gamerName ;

    public String getGamerName() {
        return gamerName;
    }

    public void setGamerName(String gamerName) {
        this.gamerName = gamerName;
    }

    public List<String> getPokes() {
        return pokes;
    }

    public void setPokes(List<String> pokes) {
        this.pokes = pokes;
    }

    public Gamer(String gamerName){
        this.gamerName = gamerName;
    }

    public int increment(){
        return atomicInteger.incrementAndGet();
    }


    public void inputHasPoke(){
        pokes.forEach(
                System.out::print
        );
        System.out.println();
    }
}

JAVA 实现扑克牌洗牌发牌 - (多线程方式):https://blog.csdn.net/qq_40990836/article/details/88338193


package cn.fllday.landlord;
 
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
/**
 * 创建一副 扑克牌
 * @author gssznb
 *
 */
public class Poker2 implements Callable<List<Brand>>{
	private static Brand[][] playingCard =new Brand[5][13];	
	/**
	 * 创建 一副 扑克牌
	 * @return
	 */
	public static Brand[][] createPlayingCard() {
		
		for (int i = 0; i < playingCard.length - 1; i++) {
			for (int j = 0; j < playingCard[i].length; j++) {
				switch (i) {
				case 0:
					playingCard[i][j] = new Brand(Type.RED,new Integer(j));
					break;
				case 1:
					playingCard[i][j] = new Brand(Type.BLACK,new Integer(j));
					break;
				case 2:
					playingCard[i][j] = new Brand(Type.PLUM,new Integer(j));
					break;
				case 3:
					playingCard[i][j] = new Brand(Type.SQUARE,new Integer(j));
					break;
				default:
					break;
				}
			}
		}
		
		playingCard[4][0] = new Brand(Type.GHOST, 14);
		playingCard[4][1] = new Brand(Type.GHOST, 15);
		for (Brand[] brands : playingCard) {
			for (Brand brand : brands) {
				System.out.print(brand);
			}
			System.out.println();
		}
		return playingCard;
	}
	
	
	public static List<Brand> getCard(Brand[][] playingCard) {
		
		// 创建一个集合, 用作 存储底牌
		List<Brand> card = new ArrayList<>();
		// 创建一个计数器。 前三次拿出三张牌。用作底牌
		int count = 0;
		while (true) {
			int i = new Random().nextInt(5);
			int j = new Random().nextInt(13);
			Brand brand = playingCard[i][j];
			if (count < 3) {
				if (brand != null) {
					// 拿出的牌放入到底牌 集合中
					card.add(brand);
					count ++;
					// 将原来扑克牌拿出牌的哪个位置设置为空
					playingCard[i][j] = null;
				}
			}else {
				break;
			}	
		}
		return card;
	}
	
	/**
	 * 将取出三张底牌的剩余牌 拿出来  发放给三位玩家
	 * @param playingCard
	 * @return  返回 每一位玩家的手牌
	 */
	public static List<Brand> licensing(Brand[][] playingCard) {
		List<Brand> card = new ArrayList<>();
		while (true) {
			int i = new Random().nextInt(5);
			int j = new Random().nextInt(13);
			
			// 每一位玩家手中的牌少于 17 
			if (card.size() < 17) {
				// 对公共资源进行加锁。
				synchronized(playingCard) {
					// 获取一张卡牌
					Brand brand = playingCard[i][j];
					// 不为空就添加到玩家手牌中
					if (brand!=null) {
						card.add(brand);
						System.out.println(Thread.currentThread().getName() + ":" +brand);
						// 添加到手牌中,就将 该位置的卡牌设置为null
						playingCard[i][j] = null;
					}	
				}
				
			}else {
				break;
			}
		}
		return card;
	}
	
 
	@Override
	public List<Brand> call() throws Exception {
		List<Brand> licensing = licensing(playingCard);
		return licensing;
	}
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		System.out.println("初始化一副扑克牌======");
		Brand[][] pokers = createPlayingCard();
		System.out.println("洗牌并筛选出斗地主中需要剩余的三张底牌");
		List<Brand> card = getCard(pokers);
		System.out.println(card);
		System.out.println("发牌中。。。。");
		// 创建一个线程池
		ExecutorService pool = Executors.newFixedThreadPool(3);
		// 创建有返回值的任务
		List<Future> list = new ArrayList<>();
		for (int i =0;i < 3; i++) {
			Callable callable= new Poker2();
			Future f = pool.submit(callable);
			list.add(f);
		}
		pool.shutdown();
		// 获取所有并发任务的执行结果
		for (Future f : list) {
			System.out.println(f.isDone());
			if (f.isDone()) {
				Object o = f.get();
				System.out.println(o);
			}
		}
	}
 
 
}