多线程练习

练习1:抢红包

假设:100块分成了3个红包,现在有5个人去抢

其中红包是共享数据,5个人是5条线程

打印结果如下:

XXX抢到了XXX元

XXX抢到了XXX元

XXX抢到了XXX元

XXX没抢到

XXX没抢到

package a05threaddemo;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Random;

public class MyThread extends Thread {
    static BigDecimal money =BigDecimal.valueOf(100.0);
    static int count = 3;
    static final BigDecimal MIN = BigDecimal.valueOf(0.01);

    public void run() {
        synchronized (MyThread.class) {
            if (count == 0) {
                System.out.println(getName() + "没有抢到红包!");
            } else {
                //定义一个变量用来表示中奖的金额
                BigDecimal prize;
                if (count == 1) {
                    //此时表示最后一个红包,就无需随机,剩余所有的钱都是中奖金额
                    prize = money;
                } else {
                    Random r = new Random();
                    //第一个红包最大是99.98
                    double bounds =money.subtract(BigDecimal.valueOf(count-1).multiply(MIN)).doubleValue();
                    prize = BigDecimal.valueOf(r.nextDouble(bounds));
                }
                //设置抽中红包,小数点保留两位,四舍五入
                prize=prize.setScale(2, RoundingMode.HALF_UP);
                //从money中去掉当前中奖的金额
                money = money .subtract(prize);
                count--;
                System.out.println(getName()+"抢到了"+prize+"元");
            }
        }
    }

}

测试类:

package a05threaddemo;

public class Test {
    public static void main(String[] args) {
        //1.创建线程的对象
        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("小B");
        t3.setName("小C");
        t4.setName("小D");
        t5.setName("小E");
        //启动线程
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

运行结果:

练习2:抽奖箱抽奖

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

{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 a05threaddemo;

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

public class MyThread1 extends Thread{
    ArrayList<Integer> list;

    public MyThread1(ArrayList<Integer> list) {
        this.list = list;
    }
    public void run(){
        while (true){
            synchronized (MyThread1.class){
                if(list.size()==0){
                    break;
                }else{
                    Collections.shuffle(list);
                    int  prize = list.remove(0);
                    System.out.println(getName()+"又产生了一个"+prize+"元大奖");
                }
            }
            try {
                Thread.sleep(10);//让结果尽可能平均
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

测试类:

package a05threaddemo;

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

public class Test1 {
    public static void main(String[] args) {
        //创建奖池
        ArrayList<Integer> list=new ArrayList<>();
        Collections.addAll(list,10,5,20,50,100,200,500,800,2,80,300,700);
        //创建线程
        MyThread1 t1=new MyThread1(list);
        MyThread1 t2=new MyThread1(list);
        //设置名字
        t1.setName("抽奖箱1");
        t2.setName("抽奖箱2");
        //启动线程
        t1.start();
        t2.start();
    }
}

运行结果:

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值