模拟多线程,两人分发100个不同类型的礼物,少于10个时停止,统计发放数量的小练习(3.17)

需求:

        小明小红2人,分发礼物,礼物有好几类,总共有100个礼物,当发到少于10个时,不再发放,最后统计小明小红二人发放的数量。

思路:

        (悲观锁)设置线程类GiftSender继承,重写run方法,同时定义数组里的礼物类型,随机数模拟100,然后加锁循环(我用的类.class;也可以专门上一个锁);然后计数统计,调get方法返回。

        在主函数main方法里,再新建对象,启动,用join等执行完;再统计打印。

代码:

线程类GiftSender
import java.util.Random;

public class GiftSender implements Runnable {
    private static final String[] GIFTS = {"玩具", "书籍", "文具", "零食", "衣服"};
    private static int giftCount = 100; // 礼物总数

    private static int xiaomingCount = 0; // 小明发放的礼物数量
    private static int xiaohongCount = 0; // 小红发放的礼物数量

    private final String senderName; // 发送者的名字

    public GiftSender(String senderName) {
        this.senderName = senderName;
    }

    @Override
    public void run() {
        Random random = new Random();
        while (true) {
            synchronized (GiftSender.class) {
                if (giftCount < 10) {
                    break; // 礼物数量小于10时停止发放
                }
                giftCount--; // 减少礼物数量
                String gift = GIFTS[random.nextInt(GIFTS.length)]; // 随机选择一个礼物
                if (senderName.equals("小明")) {
                    xiaomingCount++;
                } else {
                    xiaohongCount++;
                }
                System.out.println(senderName + " 发放了第 " + (100 - giftCount) + " 个礼物: " + gift);
            }
            try {
                Thread.sleep(random.nextInt(100)); // 模拟发放礼物的时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static int getXiaomingCount() {
        return xiaomingCount;
    }

    public static int getXiaohongCount() {
        return xiaohongCount;
    }
}

测试类Main类

public class Main {
    public static void main(String[] args) {
        // 创建两个线程,分别代表小明和小红
        Thread xiaomingThread = new Thread(new GiftSender("小明"));
        Thread xiaohongThread = new Thread(new GiftSender("小红"));

        // 启动线程
        xiaomingThread.start();
        xiaohongThread.start();

        // 等待线程结束
        try {
            xiaomingThread.join();
            xiaohongThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 统计并打印结果
        System.out.println("礼物发放结束。");
        System.out.println("小明共发放了 " + GiftSender.getXiaomingCount() + " 个礼物。");
        System.out.println("小红共发放了 " + GiftSender.getXiaohongCount() + " 个礼物。");
    }
}

扩展:

        乐观锁:AtomicInteger 的 compareAndSet 方法是乐观锁的核心,它会检查当前值是否与预期值一致,如果一致则更新,否则重试。使用AtomicInteger方法对数量进行判断。

扩展代码:

GiftSender类

import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

public class GiftSender implements Runnable {
    private static final String[] GIFTS = {"玩具", "书籍", "文具", "零食", "衣服"};
    private static final AtomicInteger giftCount = new AtomicInteger(100); // 礼物总数,使用 AtomicInteger
    private static final AtomicInteger xiaomingCount = new AtomicInteger(0); // 小明发放的礼物数量
    private static final AtomicInteger xiaohongCount = new AtomicInteger(0); // 小红发放的礼物数量

    private final String senderName; // 发送者的名字

    public GiftSender(String senderName) {
        this.senderName = senderName;
    }

    @Override
    public void run() {
        Random random = new Random();
        while (true) {
            int currentGiftCount = giftCount.get(); // 获取当前礼物数量
            if (currentGiftCount < 10) {
                break; // 礼物数量小于10时停止发放
            }

            // 尝试减少礼物数量(乐观锁的核心)
            if (giftCount.compareAndSet(currentGiftCount, currentGiftCount - 1)) {
                String gift = GIFTS[random.nextInt(GIFTS.length)]; // 随机选择一个礼物
                if (senderName.equals("小明")) {
                    xiaomingCount.incrementAndGet(); // 增加小明发放的礼物数量
                } else {
                    xiaohongCount.incrementAndGet(); // 增加小红发放的礼物数量
                }
                System.out.println(senderName + " 发放了第 " + (100 - currentGiftCount + 1) + " 个礼物: " + gift);
            }

            try {
                Thread.sleep(random.nextInt(100)); // 模拟发放礼物的时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static int getXiaomingCount() {
        return xiaomingCount.get();
    }

    public static int getXiaohongCount() {
        return xiaohongCount.get();
    }
}

Main类

public class Main {
    public static void main(String[] args) {
        // 创建两个线程,分别代表小明和小红
        Thread xiaomingThread = new Thread(new GiftSender("小明"));
        Thread xiaohongThread = new Thread(new GiftSender("小红"));

        // 启动线程
        xiaomingThread.start();
        xiaohongThread.start();

        // 等待线程结束
        try {
            xiaomingThread.join();
            xiaohongThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 统计并打印结果
        System.out.println("礼物发放结束。");
        System.out.println("小明共发放了 " + GiftSender.getXiaomingCount() + " 个礼物。");
        System.out.println("小红共发放了 " + GiftSender.getXiaohongCount() + " 个礼物。");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值