Java 多线程案例

2023-10-26

多线程解题套路

  1. 循环
  2. 同步代码块
  3. 判断共享数据(已经到末尾)
  4. 判断共享数据(没有到末尾)

案例一

需求:
一共有1000张电影票,可以在两个窗口领取,假设每次领取的时间为3000毫秒,
请用多线程模拟卖票过程并打印剩余电影票的数量

代码实现:

package com.liming.mytest;

public class Test01 {
    /*  需求:
        一共有1000张电影票,可以在两个窗口领取,假设每次领取的时间为3000毫秒,
        请用多线程模拟卖票过程并打印剩余电影票的数量
        */
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        t1.setName("窗口1");
        t2.setName("窗口2");
        t1.start();
        t2.start();
    }
}

class MyThread extends Thread{
    //第一种方式实现多线程,测试类中MyThread会创建多次,所以需要加static
    static int ticket = 1000;

    @Override
    public void run() {
        //1、循环
        while (true){
            //2、同步代码块
            synchronized (MyThread.class){
                //3、判断共享数据(已经到末尾)
                if (ticket == 0){
                    break;
                }else {
                    //4、判断共享数据(没有到末尾)
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ticket--;
                    System.out.println(getName()+"在卖票,还剩"+ticket+"张电影票");
                }
            }
        }
    }
}

案例二

有100份礼品,两人同时发送,当剩下的礼品小于10份的时候则不再送出。
利用多线程模拟该过程并将线程的名字和礼物的剩余数量打印出来.

代码实现:

package com.liming.mytest;

public class Test02 {
    public static void main(String[] args) {
        /*
        有100份礼品,两人同时发送,当剩下的礼品小于10份的时候则不再送出。
        利用多线程模拟该过程并将线程的名字和礼物的剩余数量打印出来.
        */
        MyRun mr = new MyRun();
        Thread t1 = new Thread(mr,"窗口1");
        Thread t2 = new Thread(mr,"窗口2");
        t1.start();
        t2.start();
    }
}

class MyRun implements Runnable{
    //第二种方式实现多线程,测试类中MyRunable只创建一次,所以不需要加static
    int count = 100;

    @Override
    public void run() {
        //1、循环
        while (true){
            //2、同步代码块
            synchronized (MyRun.class){
                //3、判断共享数据(已经到末尾)
                if (count <= 10){
                    System.out.println("礼物还剩下"+count+"份不在送出");
                    break;
                }else {
                    //4.判断共享数据(没有到末尾)
                    count--;
                    System.out.println(Thread.currentThread().getName() + "在赠送礼物,还剩下" + count + "个礼物!!!");
                }
            }
        }
    }
}

案例三

同时开启两个线程,共同获取1-100之间的所有数字。
输出所有的奇数。

代码实现:

package com.liming.mytest;

public class Test03 {
    public static void main(String[] args) {
        /*同时开启两个线程,共同获取1-100之间的所有数字。
        将输出所有的奇数。*/

        MyRun01 mr = new MyRun01();
        Thread t1 = new Thread(mr,"线程A");
        Thread t2 = new Thread(mr,"线程B");
        t1.start();
        t2.start();
    }
}

class MyRun01 implements Runnable {
    int i = 1;

    @Override
    public void run() {
        //1.循环
        while (i <= 100) {
            //2、同步代码块
            synchronized (MyRun01.class) {
                //3、判断共享数据(已经到末尾)
                if (i > 100) {
                    break;
                } else {
                    //4、判断共享数据(没到末尾)
                    if (i % 2 != 0){
                        System.out.println(Thread.currentThread().getName()+"打印数字"+i);
                    }
                    i++;
                }
            }
        }
    }
}

案例四

假设:100块,分成了3个包,现在有5个人去抢。
其中,红包是共享数据。5个人是5条线程。
打印结果如下:
XXX抢到了XXX元
XXX抢到了XXX元
XXX抢到了XXX元
XXX没抢到
XXX没抢到

代码实现:

package com.liming.mytest;

import java.util.Random;

public class Test04 {
    public static void main(String[] args) {
         /*
    假设:100块,分成了3个包,现在有5个人去抢。
    其中,红包是共享数据。5个人是5条线程。
    打印结果如下:
    XXX抢到了XXX元
    XXX抢到了XXX元
    XXX抢到了XXX元
    XXX没抢到
    XXX没抢到
    */

        //创建线程的对象
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        MyThread t3 = new MyThread();
        MyThread t4 = new MyThread();
        MyThread t5 = new MyThread();

        //给线程设置名字
        t1.setName("小A");
        t2.setName("小QQ");
        t3.setName("小哈哈");
        t4.setName("小诗诗");
        t5.setName("小丹丹");

        //启动线程
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

class MyThread01 extends Thread {
    //共享数据,100元,三个红包
    static double money = 100;
    static int count = 3;

    //最小的中奖金额
    static final double MIN = 0.01;

    @Override
    public void run() {
        //同步代码块
        synchronized (MyThread01.class) {
            if (count == 0) {
                //判断共享数据(已经到末尾)
                System.out.println(getName() + "没有抢到红包!");
            } else {
                //判断共享数据(没有到末尾)
                //定义一个变量表示中奖金额
                double prize = 0;
                if (count == 1) {
                    //表示此时是最后一个红包
                    //就无需随机,剩余所有的钱都是中奖金额
                    prize = money;
                } else {
                    //表示第一次,第二次(随机)
                    Random r = new Random();
                    //100 元   3个包
                    //第一个红包:99.98
                    //100 - (3-1) * 0.01
                    double bounds = money - (count - 1) * MIN;//最大中奖金额
                    prize = r.nextDouble(bounds);
                    if (prize < MIN) {
                        prize = MIN;
                    }
                }
                money = money - prize;
                count--;
                System.out.println(getName() + "抢到了:" + prize + "元");
            }
        }
    }
}

案例五

有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为 {10,5,20,50,100,200,500,800,2,80,300,700};
创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”
随机从抽奖池中获取奖项元素并打印在控制台上,格式如下:
每次抽出一个奖项就打印一个(随机)
抽奖箱1 又产生了一个 10 元大奖
抽奖箱1 又产生了一个 100 元大奖
抽奖箱1 又产生了一个 200 元大奖
抽奖箱1 又产生了一个 800 元大奖
抽奖箱2 又产生了一个 700 元大奖…

代码实现:

package com.liming.mytest;

import java.util.ArrayList;
import java.util.Collections;

public class Test05 {
    public static void main(String[] args) {
        /*需求:
        有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为 {10,5,20,50,100,200,500,800,2,80,300,700};
        创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”
        随机从抽奖池中获取奖项元素并打印在控制台上,格式如下:
        每次抽出一个奖项就打印一个(随机)
        抽奖箱1 又产生了一个 10 元大奖
        抽奖箱1 又产生了一个 100 元大奖
        抽奖箱1 又产生了一个 200 元大奖
        抽奖箱1 又产生了一个 800 元大奖
        抽奖箱2 又产生了一个 700 元大奖...
         */
        //创建奖池
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list,10,5,20,50,100,200,500,800,2,80,300,700);

        //创建线程
        MyThread02 t1 = new MyThread02(list);
        MyThread02 t2 = new MyThread02(list);

        t1.setName("窗口1");
        t2.setName("窗口2");

        //开启线程
        t1.start();
        t2.start();
    }
}

class MyThread02 extends Thread{
    ArrayList<Integer> arrayList;
    public MyThread02(ArrayList<Integer> arrayList){
        this.arrayList = arrayList;
    }

    @Override
    public void run() {
        while (true){
            synchronized (MyThread02.class){
                if (arrayList.size() == 0){
                    break;
                }else {
                    Collections.shuffle(arrayList);
                    int prize = arrayList.remove(0);
                    System.out.println(getName()+"产生了"+prize+"元大奖");
                }
            }
        }
    }
}

案例六

在上一题基础上继续完成如下需求:
每次抽的过程中,不打印,抽完时一次性打印(随机)
在此次抽奖过程中,抽奖箱1总共产生了6个奖项。
分别为:10,20,100,500,2,300最高奖项为300元,总计额为932元
在此次抽奖过程中,抽奖箱2总共产生了6个奖项。
分别为:5,50,200,800,80,700最高奖项为800元,总计额为1835元

代码实现:

package com.liming.mytest;

import java.util.ArrayList;
import java.util.Collections;

public class Test06 {
    public static void main(String[] args) {
        /*需求:
        在上一题基础上继续完成如下需求:
        每次抽的过程中,不打印,抽完时一次性打印(随机)
        在此次抽奖过程中,抽奖箱1总共产生了6个奖项。
        分别为:10,20,100,500,2,300最高奖项为300元,总计额为932元
        在此次抽奖过程中,抽奖箱2总共产生了6个奖项。
        分别为:5,50,200,800,80,700最高奖项为800元,总计额为1835元*/

        //创建奖池
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list,10,5,20,50,100,200,500,800,2,80,300,700);

        //创建线程
        MyThread03 t1 = new MyThread03(list);
        MyThread03 t2 = new MyThread03(list);


        //设置名字
        t1.setName("抽奖箱1");
        t2.setName("抽奖箱2");


        //启动线程
        t1.start();
        t2.start();
    }
}
class MyThread03 extends Thread{
    ArrayList<Integer> list;

    public MyThread03(ArrayList<Integer> list) {
        this.list = list;
    }

    @Override
    public void run() {
        ArrayList<Integer> boxList = new ArrayList<>();//1 //2
        while (true) {
            synchronized (MyThread.class) {
                if (list.size() == 0) {
                    System.out.println(getName() + boxList);
                    break;
                } else {
                    //继续抽奖
                    Collections.shuffle(list);
                    int prize = list.remove(0);
                    boxList.add(prize);
                }
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 多线程案例 的相关文章

随机推荐

  • QT之模态

    模态 当一个窗口以模态显示 那么所有其他窗口的事件都被阻塞 停止运行 直到模态窗口关闭后才继续 MainWindow pMainWindow new MainWindow pMainWindow gt setWindowTitle QStr
  • Hbuilder X用不习惯?快来看看这些快捷键

    用惯了vscode Hbuilder X的使用也得熟练 快捷键如下 Ctrl N 新建文件 Ctrl W 关闭文件 Ctrl Shift W 关闭全部文件 Ctrl S 保存文件 Ctrl Shift S 保存全部文件 Alt 激活代码助手
  • C/C++的单元/集成测试工具 - VectorCAST/C++

    什么是VectorCAST C VectorCAST C 是一套集成的软件测试解决方案 能显著降低C C 测试过程中为达到安全性检测和嵌入式系统关键任务检测所必需的时间 工作量及成本 VectorCAST C 可自动实现 为单元测试和集成测
  • (USB系列三)stm32 CubeMX usb音频描述符详解 usb audio UAC

    如果需要麦克风阵列 回声消除 声源定位 波束成形 语音对话的产品请访问我好朋友的店铺 店铺链接 首页 智能语音开发者联盟 淘宝网 大家好我是人见人爱 花见花开的大魔王 usb协议还是很烦的 cube很大程度上减轻了工作量 但是不灵活是个大问
  • python xlrd主要功能

    This module is part of the xlrd package which is released under a BSD style licence Basically use function xlrd open wor
  • 信息学奥赛--进制转化

    学习目标 1 了解二进制及其他进制 2 十进制与R进制的转换 3 能编程实现进制之间的转换 学习内容 练习 一 任意进制转十进制 1 1101101 2 2 7754 8 3 F1B9AC 16 4 1011 11101 2 5 75 10
  • 开源BT磁力搜索引擎收集

    基本是利用bt网络中p2p技术实现 开源项目上实现了dht网络的搜索 是学习dht算法的好项目 https lanmaowz com open dht spider https github com dontcontactme p2pspi
  • NVIDIA Jetson TX2 解决奥比中光 Astra pro相机的ros 打不开深度信息/camera/depth/image

    背景 NVIDIA Jetson TX2 安装奥比中光 Astra pro相机的ROS 驱动后可以打开彩色相机 打不开深度信息 有点捉急 换了一台相机 还是如此 说明相机没问题驱动有问题 打开奥比中光的开发者论坛 Astra pro无法读取
  • SDN 中 DDoS 攻击问题(论文方法总结)

    SDN 中 DDoS 攻击类型 1 数据平面DDoS攻击 数据平面由多个启用OpenFlow的转发设备组成 这些设备被称为OpenFlow交换机 每个交换机都有一个有限的流表大小来存储规则和有限的处理能力来处理不匹配的数据包 因此 它成为缓
  • rancher部署flink集群

    rancher版本 v2 6 8 k8s版本 v1 22 13 rke2r1 flink集群版本 1 15 0 flink安装模式 session cluster 写在前面 因为参照官网的说明安装过程中出现了很多问题 特记录于此 避免后续重
  • 2020-6-19 Idea打包项目war并且发布到服务器

    打包的介绍 打包和上传到服务器的介绍
  • linux操作系统发行版_Linux操作系统和发行版

    linux操作系统发行版 Newcomers to Linux world generally confuse or no idea about distributions We call generally the operating s
  • ChatGPT能代替搜索引擎吗?ChatGPT和搜索引擎有什么区别?

    ChatGPT和搜索引擎是两种在信息获取和交流中常用的工具 ChatGPT是一种基于人工智能技术的聊天机器人 而搜索引擎是一种在互联网上搜索信息的工具 尽管它们都是依托互联网与信息获取和交流有关 部分功能重合 但在很多方面存在着明显的区别
  • JS逆向

    关注它 不迷路 本文章中所有内容仅供学习交流 不可用于任何商业用途和非法用途 否则后果自负 如有侵权 请联系作者立即删除 1 需求 最近美食群发了很多二维码 提取链接后 可以在移动端的浏览器上愉快的播放 然而 当我把 url 链接复制到 我
  • mac安装vue

    需要提前安装brew 安装方法 mac使用Homebrew安装node 1 安装node 上面链接已经详细介绍如何安装node 这里一笔带过 brew install nodejs node v 2 安装webpack cnpm insta
  • 令人眼花缭乱的区块链名词之:UTXO

    目录 1 交易 2 UTXO hello 大家好 我们第六期的区块链技术分享来啦 本期分享的主题是UTXO Unspent Transaction output 未花费的交易输出 在比特币系统中 每个全节点都会记录UTXO 要理解UTXO模
  • python 爬取今日头条热点新闻

    嗯 今天就让我们来一起爬爬今日头条的热点新闻吧 今日头条地址 https www toutiao com ch news hot 在浏览器中打开今日头条的链接 选中左侧的热点 在浏览器开发者模式 network下很快能找到一个 catego
  • Qt应用程序自动重启(零零散散)

    老有人问如何让Qt的应用程序自动重启 稍微写一点 也顺便理理自己的思路 2011 10 26 自动重启 也就是退出当前进程 启动一个新的进程 于是 先看程序如何退出 退出 Qt程序的一般结构如下 int main int argc char
  • 【Java入门杂记】

    文章目录 快捷键 转义符 数据类型 变量 变量名命名规则 交换数值 运算符 逻辑运算符 Scanner 条件语句 循环语句 字符匹配 随机数 二分查找 快捷键 javac与新建系统变量的java路径有关 atl 补齐敏感提示 Ctrl D
  • Java 多线程案例

    多线程解题套路 循环 同步代码块 判断共享数据 已经到末尾 判断共享数据 没有到末尾 案例一 需求 一共有1000张电影票 可以在两个窗口领取 假设每次领取的时间为3000毫秒 请用多线程模拟卖票过程并打印剩余电影票的数量 代码实现 pac