多线程练习小案例

简介: java新手多线程案例
1、多线程练习1(卖电影票)

一共有1000张电影票,可以在两个窗口领取,假设每次领取的时间为3000毫秒。

要求:用多线程模拟买票过程并打印剩余电影票的数量

创建Ticket类

package com.lwj.Thread.demo.test1;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Ticket extends Thread{
   

    static int ticket = 1000;
    static Lock lock = new ReentrantLock();


    @Override
    public void run() {
   
        while (true){
   
            lock.lock();
            try {
   
                if (ticket > 0){
   
                        Thread.sleep(30);
                        ticket--;
                        System.out.println(getName() + "卖出了1张票,还剩下:" + ticket);
                } else {
   
                    break;
                }
            } catch (InterruptedException e) {
   
                throw new RuntimeException(e);
            } finally {
   
                lock.unlock();
            }
        }
    }
}

创建测试类TicketDemo

package com.lwj.Thread.demo.test1;

public class TicketDemo {
   
    public static void main(String[] args) {
   

        //创建对象
        Ticket t1 = new Ticket();
        Ticket t2 = new Ticket();

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

        t1.start();
        t2.start();

    }
}
2、多线程练习2(送礼品)

有100份礼品,两个人同时发送,当剩下的礼品小于10份的时候,则不再送出。

要求:利用多线程模拟该过程并将线程的名字和礼物的剩余数量打印出来

创建gift类

package com.lwj.Thread.demo.test2;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class gift extends Thread{
   

    static Lock lock = new ReentrantLock();
    static int Gift = 100;


    @Override
    public void run() {
   


        while (true){
   
            lock.lock();
            try {
   
                Thread.sleep(30);
                if (Gift < 10){
   
                    break;
                } else {
   
                    Gift--;
                    System.out.println(getName() + "送出了一份礼物,还剩下"+Gift);
                }
            } catch (InterruptedException e) {
   
                throw new RuntimeException(e);
            } finally {
   
                lock.unlock();
            }
        }
    }
}

创建线程测试类

package com.lwj.Thread.demo.test2;

public class giftDemo {
   
    public static void main(String[] args) {
   
        //创建线程对象
        gift g1 = new gift();
        gift g2 = new gift();

        g1.setName("小明");
        g2.setName("小红");

        g1.start();
        g2.start();
    }
}
3、多线程练习3(打印奇数数字)

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

要求:输出所有的奇数

创建线程类

package com.lwj.Thread.demo.test3;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Number extends Thread{
   

    static int i = 0;
    @Override
    public void run() {
   
        synchronized (this) {
   
            try {
   
                Thread.sleep(100);
            } catch (InterruptedException e) {
   
                throw new RuntimeException(e);
            }
            for (i = 0; i < 100; i++) {
   
                if (i % 2 != 0) {
   
                    System.out.println(getName() + i);
                }
            }
        }
    }
}

创建线程测试类

package com.lwj.Thread.demo.test3;

public class NumberTest {
   
    public static void main(String[] args) {
   
        //创建对象
        Number number01 = new Number();
        Number number02 = new Number();

        number01.setName("线程1:");
        number02.setName("线程2:");

        number01.start();
        number02.start();

    }
}
4、多线程练习4(抢空包)

抢红包也用到了多线程

假设:100块,分成了3个包,现在5个人去抢,其中红包的数据共享,5个人是5条线程

要求: 打印结果如下

  • xxx抢到了xxx元
  • xxx抢到了xxx元
  • xxx抢到了xxx元
  • xxx没抢到
  • xxx没抢到

创建线程类

package com.lwj.Thread.demo.test4;


import java.util.Random;

public class RedEnvelop extends Thread{
   
    static double redenvelop = 100;
    static int count = 3;

    static final  double MIN = 0.01;

    @Override
    public void run() {
   
       synchronized (RedEnvelop.class){
   
           if (count == 0){
   
               System.out.println(getName()+"没有抢到红包");
           } else {
   
               double prize = 0;
               if (count == 1 ){
   
                   prize = redenvelop;
               } else {
   
                   Random random = new Random();

                   double bounds = redenvelop - (count -1) * MIN;

                   prize = random.nextDouble(bounds);

                   if (prize < MIN) {
   
                       prize = MIN;
                   }
               }
               redenvelop = redenvelop - prize;
               count--;
               System.out.println(getName() + "中奖" + prize);
           }

       }
    }
}

创建测试类

public class RedEnvlopDemo {
   
    public static void main(String[] args) {
   

        RedEnvelop redEnvelop01 = new RedEnvelop();
        RedEnvelop redEnvelop02 = new RedEnvelop();
        RedEnvelop redEnvelop03 = new RedEnvelop();
        RedEnvelop redEnvelop04 = new RedEnvelop();
        RedEnvelop redEnvelop05 = new RedEnvelop();

        redEnvelop01.setName("1号");
        redEnvelop02.setName("2号");
        redEnvelop03.setName("3号");
        redEnvelop04.setName("4号");
        redEnvelop05.setName("5号");

        redEnvelop01.start();
        redEnvelop02.start();
        redEnvelop03.start();
        redEnvelop04.start();
        redEnvelop05.start();
    }
}
5、多线程练习5(抽奖箱抽奖)

有一个抽奖池中存放了奖励的金额,该抽奖池中的奖项为

​ {10,5,50,100,200,500,800,2,80,300,700}

创建两个抽奖箱线程 ,设置线程名分别为“抽奖箱1”,“抽奖箱2”,随机从奖池中获取奖项元素并打印在控制台。

格式:

  • 抽奖1产生1个10元大奖
  • 抽奖1产生1个100元大奖
  • 抽奖2产生1个800元大奖
  • ...........

创建线程类

package com.lwj.Thread.demo.test5;

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

public class DrawBox extends Thread{
   
    ArrayList<Integer> arrayList;

    public DrawBox(ArrayList arrayList){
   
        this.arrayList = arrayList;
    }

    @Override
    public void run() {
   
       while (true){
   
           synchronized (DrawBox.class){
   
               if (arrayList.size() == 0){
   
                   break;
               } else {
   
                   Collections.shuffle(arrayList);      //打乱数组
                   Integer remove = arrayList.remove(0);
                   System.out.println(getName()+ "产生了" + remove);
               }
           }
        }
    }
}

创建测试类

package com.lwj.Thread.demo.test5;

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

public class DrawBoxDemo {
   
    public static void main(String[] args) {
   

        ArrayList<Integer> arrayList = new ArrayList<>();
        Collections.addAll(arrayList,10,5,50,100,200,500,800,2,80,300,700);

        DrawBox drawBox01 = new DrawBox(arrayList);
        DrawBox drawBox02 = new DrawBox(arrayList);

        drawBox01.setName("抽奖箱1");
        drawBox02.setName("抽奖箱2");

        drawBox01.start();
        drawBox02.start();

    }
}
6、多线程练习6(多线程统计并求最大值)

在上一题基础上继续完成如下需求:

​ 每次抽中过程中不打印,抽完时一次性打印(随机)

​ 在此抽奖中,抽奖箱1总共产生了6个奖项

​ 分别是 10,20,100,500,2,300最高奖项为300元,总共额为932

​ 在此抽奖中,抽奖箱1总共产生了6个奖项

​ 分别为:5,50,200,800,80,700最高奖项为800元,总计额为1835元

创建线程类

package com.lwj.Thread.demo.test5;

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

public class DrawBox extends Thread{
   
    ArrayList<Integer> arrayList;

    public DrawBox(ArrayList arrayList){
   
        this.arrayList = arrayList;
    }

    static ArrayList<Integer> list01 = new ArrayList<>();
    static ArrayList<Integer> list02 = new ArrayList<>();

    @Override
    public void run() {
   
       while (true){
   
           synchronized (DrawBox.class){
   
               if (arrayList.size() == 0){
   
                   if ("抽奖箱1".equals(getName())){
   
                       String str = print(list01);
                       int max = max(list01);
                       System.out.println(getName()+"产生了"+str+"最高为"+max);
                   } else {
   
                       String str = print(list02);
                       int max = max(list02);
                       System.out.println(getName()+"产生了"+str+"最高为"+max);
                   }
                   break;
               } else {
   
                   Collections.shuffle(arrayList);      //打乱数组
                   Integer money = arrayList.remove(0);
                   if ("抽奖箱1".equals(getName())){
   
                       list01.add(money);
                   } else {
   
                       list02.add(money);
                   }
               }
           }
        }
    }

    public String print(ArrayList<Integer> arrayList){
   
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < arrayList.size(); i++) {
   
           if ( i == arrayList.size()-1){
   
               stringBuilder.append(arrayList.get(i));
           } else {
   
               stringBuilder.append(arrayList.get(i));
               stringBuilder.append(",");
           }
        }
        return String.valueOf(stringBuilder);
    }

    public int  max(ArrayList<Integer> arrayList){
   
        int max = arrayList.get(0);
        for (int i = 0; i < arrayList.size(); i++) {
   
            if (arrayList.get(i) > max){
   
                max = arrayList.get(i);
            }
        }
        return max;
    }
}

创建线程测试类

package com.lwj.Thread.demo.test5;

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

public class DrawBoxDemo {
   
    public static void main(String[] args) {
   

        ArrayList<Integer> arrayList = new ArrayList<>();
        Collections.addAll(arrayList,10,5,50,100,200,500,800,2,80,300,700);

        DrawBox drawBox01 = new DrawBox(arrayList);
        DrawBox drawBox02 = new DrawBox(arrayList);

        drawBox01.setName("抽奖箱1");
        drawBox02.setName("抽奖箱2");

        drawBox01.start();
        drawBox02.start();

    }
}
相关文章
|
8月前
|
存储 监控 Java
JAVA线程池有哪些队列? 以及它们的适用场景案例
不同的线程池队列有着各自的特点和适用场景,在实际使用线程池时,需要根据具体的业务需求、系统资源状况以及对任务执行顺序、响应时间等方面的要求,合理选择相应的队列来构建线程池,以实现高效的任务处理。
341 12
|
设计模式 监控 Java
Java多线程基础-11:工厂模式及代码案例之线程池(一)
本文介绍了Java并发框架中的线程池工具,特别是`java.util.concurrent`包中的`Executors`和`ThreadPoolExecutor`类。线程池通过预先创建并管理一组线程,可以提高多线程任务的效率和响应速度,减少线程创建和销毁的开销。
732 2
|
Java Python 开发者
Python 学习之路 01基础入门---【Python安装,Python程序基本组成】
线程池详解与异步任务编排使用案例-xian-cheng-chi-xiang-jie-yu-yi-bu-ren-wu-bian-pai-shi-yong-an-li
559 3
Python 学习之路 01基础入门---【Python安装,Python程序基本组成】
|
安全 Java
Java多线程基础-10:代码案例之定时器(一)
`Timer` 是 Java 中的一个定时器类,用于在指定延迟后执行指定的任务。它常用于实现定时任务,例如在网络通信中设置超时或定期清理数据。`Timer` 的核心方法是 `schedule()`,它可以安排任务在延迟一段时间后执行。`
263 1
|
Python
Python学习之路 02 之分支结构
Python学习之路 02 之分支结构
558 0
Python学习之路 02 之分支结构
|
SQL Dubbo Java
案例分析|线程池相关故障梳理&总结
本文作者梳理和分享了线程池类的故障,分别从故障视角和技术视角两个角度来分析总结,故障视角可以看到现象和教训,而技术视角可以透过现象看到本质更进一步可以看看如何避免。
84903 136
案例分析|线程池相关故障梳理&总结
|
11月前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
147 1
|
Java
线程池详解与异步任务编排使用案例-xian-cheng-chi-xiang-jie-yu-yi-bu-ren-wu-bian-pai-shi-yong-an-li
线程池详解与异步任务编排使用案例-xian-cheng-chi-xiang-jie-yu-yi-bu-ren-wu-bian-pai-shi-yong-an-li
182 0
|
消息中间件 安全 Kafka
"深入实践Kafka多线程Consumer:案例分析、实现方式、优缺点及高效数据处理策略"
【8月更文挑战第10天】Apache Kafka是一款高性能的分布式流处理平台,以高吞吐量和可扩展性著称。为提升数据处理效率,常采用多线程消费Kafka数据。本文通过电商订单系统的案例,探讨了多线程Consumer的实现方法及其利弊,并提供示例代码。案例展示了如何通过并行处理加快订单数据的处理速度,确保数据正确性和顺序性的同时最大化资源利用。多线程Consumer有两种主要模式:每线程一个实例和单实例多worker线程。前者简单易行但资源消耗较大;后者虽能解耦消息获取与处理,却增加了系统复杂度。通过合理设计,多线程Consumer能够有效支持高并发数据处理需求。
365 4
|
12月前
|
安全 Java 调度
python3多线程实战(python3经典编程案例)
该文章提供了Python3中多线程的应用实例,展示了如何利用Python的threading模块来创建和管理线程,以实现并发执行任务。
336 0