多线程练习题1

该博客通过实现Runnable接口创建了两个抽奖线程,每个线程从预先设定的奖项池中随机抽取6个奖项,模拟抽奖过程。抽奖过程中,线程同步通过`synchronized`关键字保证了数据一致性。抽奖结束后,线程会输出所抽到的所有奖项及最高奖项和总金额。此外,还讨论了如何避免多个线程间的数据冲突问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

public class MyRunnable implements Runnable {
	static int[] arr = { 10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300, 700 }; // 共有数据
	static ArrayList<Integer> list = new ArrayList<Integer>();
	static {
		for (int m : arr) {//只要MyRunnable这个类一加载,就会将数组中的元素添加到集合中
			list.add(m);
		}
	}
	static Random ra = new Random();// 用静态修饰,减少了内存的消耗
    static int max = Collections.max(list);//最大獎項
	
	@Override
	public void run() {
		ArrayList<Integer> list1 = new ArrayList<Integer>();
		while (true) {
			//1,2
			synchronized (MyRunnable.class) {
				if (list1.size() == 6) {
					break;
				}
				int i = ra.nextInt(list.size());
				Integer remove = list.remove(i);// 抽一个少一个
				list1.add(remove);
				System.out.println(Thread.currentThread().getName());
			}
		}
		System.out.println("在此次抽奖过程中," + Thread.currentThread().getName()
				+ " 总共产生了6个奖项,分别为:" + list1 + "最高奖项为" + Collections.max(list1)
				+ "元,总计额为" + sumMethod(list1) + "元");
		
		if(list1.contains(max)){
			System.out.println("在此次抽奖过程中,"+Thread.currentThread().getName()+"中产生了最大奖项,该奖项金额为"+ max);
		}

	}

	/*//第二问
	@Override
	public void run() {
		 只需要创建一个集合,因为两个线程执行此段代码时会分别创建一个集合
		 * 两个线程在栈内存中会分别加载run方法,所以list1这个引用会有两份
		 * 两个线程在执行的过程中互不干扰
		 
		ArrayList<Integer> list1 = new ArrayList<Integer>();
		while (true) {
			//1,2
			synchronized (MyRunnable.class) {
				if (list1.size() == 6) {
					break;
				}
				int i = ra.nextInt(list.size());
				Integer remove = list.remove(i);// 抽一个少一个
				list1.add(remove);
				System.out.println(Thread.currentThread().getName());
			}
		}
		System.out.println("在此次抽奖过程中," + Thread.currentThread().getName()
				+ " 总共产生了6个奖项,分别为:" + list1 + "最高奖项为" + Collections.max(list1)
				+ "元,总计额为" + sumMethod(list1) + "元");
	}
	}*/

	/*
	 * //第一问
	 * 
	 * @Override public void run() { while(true){ synchronized
	 * (MyRunnable.class) { //对操作共有数据的代码添加同步代码块,并要保证锁的唯一性 if (list.isEmpty()) {
	 * break; } int i = ra.nextInt(list.size()); Integer remove =
	 * list.remove(i);//抽一个少一个 System.out.println(
	 * Thread.currentThread().getName() + "又产生了一个"+ remove+ "元大奖"); }
	 * 
	 * } }
	 */
	
	//求和
	private int sumMethod(ArrayList<Integer> list1) {
		int sum = 0;
		for (int m : list1) {
			sum += m;
		}
		return sum;

}}

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

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


	3.每次抽的过程中,不打印,抽完时一次性打印(随机)
		在此次抽奖过程中,抽奖箱1总共产生了6个奖项,分别为:10,20,100,500,2,300最高奖项为300元,总计额为932元
		在此次抽奖过程中,抽奖箱2总共产生了6个奖项,分别为:5,50,200,800,80,700最高奖项为800元,总计额为1835元
		在此次抽奖过程中,抽奖箱2中产生了最大奖项,该奖项金额为800元
 */
public class Test1 {
	public static void main(String[] args) {
		//创建两个线程,去共同操作MyRunnable对象
		MyRunnable mr = new MyRunnable();
		Thread t1 = new Thread(mr,"抽奖箱1");
		Thread t2 = new Thread(mr,"抽奖箱2");
		
		t1.start();
		t2.start();
		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值