黑马多线程java1-7题题解

目录

文章目录

  • 目录
    • 01卖电影票
    • 02送礼品
    • 03打印奇数数字
    • 04抢红包
    • 05 抽奖
      • 解法一(数组解法)
      • 解法二(使用ArrayList去重和判断为空)
    • 06统计并求最大值
      • 解法一用int数组
      • 解法二用ArrayList
      • 解法三 改进如果有多个线程的情况
    • 07多线程之间的比较

01卖电影票

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

package exercise1;

public class NewThread implements Runnable{
    int ticket=1000;
    @Override
    public void run() {
        while (true){
            synchronized (NewThread.class){
                if(ticket==0){
                    break;
                }else {
                    try {
                        Thread.sleep(3);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    ticket--;
                    System.out.println(Thread.currentThread().getName()+"还剩余"+ticket+"张票");
                }
            }
        }
    }
}

Main类:

package exercise1;

public class ThreadDemo {
    public static void main(String[] args) {
        NewThread item=new NewThread();
        Thread t1=new Thread(item);
        Thread t2=new Thread(item);
        t1.setName("窗口1");
        t2.setName("窗口2");
        t1.start();
        t2.start();
    }
}

02送礼品

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

package exercise2;

public class newThread extends Thread{
    public int gift=100;
    public static Object obj=new Object();
    @Override
    public void run() {
        while (true){
            synchronized (obj){
                if(gift<11){
                    break;
                }
                else{
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    gift--;
                    System.out.println(Thread.currentThread().getName()+"发放了第"+gift+"份礼物");
                }
            }
        }
    }
}

Main类:

package exercise2;

import exercise1.NewThread;

public class Main {
    public static void main(String[] args) {
        newThread run_t=new newThread();
        Thread t1=new Thread(run_t);
        Thread t2=new Thread(run_t);
        t1.setName("第一个人");
        t2.setName("22");
        t1.start();
        t2.start();
    }
}

03打印奇数数字

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

package exercise3;

public class MyThread extends Thread{
    public static int count=0;
    @Override
    public void run() {
        while (true){
            synchronized (MyThread.class){
                if(count==101){
                    break;
                }else {
                    count++;
                    if(count%2==0)
                        System.out.println(Thread.currentThread().getName()+":"+count);
                }
            }
        }
    }
}

Main类:

package exercise3;

public class Main {
    public static void main(String[] args) {
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();
        t1.setName("线程1");
        t2.setName("线程2");
        t1.start();
        t2.start();

    }
}

04抢红包

假设有100元,分成3个红包,现在有5个人去抢。

Main类:

package exercise4;

public class Main {
    public static void main(String[] args) {
        HongBaoThread t=new HongBaoThread();
        HongBaoThread t2=new HongBaoThread();
        HongBaoThread t3=new HongBaoThread();
        HongBaoThread t4=new HongBaoThread();
        HongBaoThread t5=new HongBaoThread();
        t.setName("线程1");
        t2.setName("线程2");
        t3.setName("线程3");
        t4.setName("线程4");
        t5.setName("线程5");
        t.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();



    }
}

Thread类:

package exercise4;


import java.util.Random;

public class HongBaoThread extends Thread{
    static int count=3; //红包个数
    static final double MIN=0.01; //最小红包金额
    static double money=100; //红包金额总价值

    @Override
    public void run() {
        synchronized (HongBaoThread.class){
            if(count==0){ //红包已经抢完
                System.out.println(getName()+"已抢完");
            }else{
                double prize=0; //当前红包金额
                if(count==1){ //最后一个红包
                    prize=money;
                }else {
                    Random r=new Random();
                    double bound=money-(count-1)*MIN;
                    prize=r.nextDouble(bound);
                    if(prize<MIN)
                        prize=MIN;
                }
                money-=prize;
                count--;
                System.out.println(getName()+"抢到了"+prize+"元");
            }
        }
    }
}

05 抽奖

有一个抽奖池,该抽奖池存放了奖励的金额,该抽奖池中的奖项为10,5,20,50,100,200,500,800,2,80,300,700;

创建两个抽奖箱(线程)设置线程名称分别为抽奖箱1,抽奖箱3

随机从抽奖池中获取奖项元素并打印在控制台上

解法一(数组解法)

Thread类:


package exercise5;

import java.util.Random;

public class ChouJiang extends Thread{
    static int[] prizes={10,5,20,50,100,200,500,800,2,80,300,700};
    static boolean[] flag=new boolean[prizes.length];

    public static boolean isEmpty(boolean[] flags){
        for(boolean i:flags)
            if(i==false)
                return true;
        return false;
    }
    @Override
    public void run() {

        while (true){

            synchronized (ChouJiang.class){
                boolean t_flag=isEmpty(flag);
                if(!t_flag){
                    break;
                }else{
                    Random r=new Random();
                    int index;
                    while(true){
                        index=r.nextInt(prizes.length);
                        if(flag[index]==false)
                            break;
                    }
                    flag[index]=true;
                    System.out.println(getName()+"抽到了"+prizes[index]+"元");
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}


Main类:

package exercise5;

public class Main {
    public static void main(String[] args) {
        ChouJiang t1=new ChouJiang();
        ChouJiang t2=new ChouJiang();
        t1.setName("抽奖池1");
        t2.setName("抽奖池2");
        t1.start();
        t2.start();
    }
}

解法二(使用ArrayList去重和判断为空)

Thread类:

package exercise5itcase;

import exercise5.ChouJiang;

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

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

    @Override
    public void run() {
        while(true){
            synchronized (ChouJiang.class){
                if(list.size()==0)
                    break;
                else {
                    Collections.shuffle(list);
                    int prize=list.remove(0);
                    System.out.println(getName()+"抽中了"+prize+"元");
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

Main类:

package exercise5itcase;


import exercise5.ChouJiang;

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

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> list=new ArrayList<Integer>();
        Collections.addAll(list,100,200,500,800,2,5,50,10,20);
        ChouJjiang t1=new ChouJjiang(list);
        ChouJjiang t2=new ChouJjiang(list);
        t1.setName("抽奖箱1");
        t2.setName("抽奖箱2");
        t1.start();
        t2.start();
    }
}

06统计并求最大值

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

解法一用int数组

Thread类:

package exercise6;

import exercise5.ChouJiang;

import java.util.Random;

public class MyThread extends Thread{
    static int[] prizes={10,5,20,50,100,200,500,800,2,80,300,700};
    static boolean[] flag=new boolean[prizes.length];

    static int[] prizes1=new int[prizes.length];
    static int[] prizes2=new int[prizes.length];
    static int index1=0,index2=0;

    public static boolean isEmpty(boolean[] flags){
        for(boolean i:flags)
            if(i==false)
                return true;
        return false;
    }
    @Override
    public void run() {

        while (true){

            synchronized (ChouJiang.class){
                boolean t_flag=isEmpty(flag);
                if(!t_flag){
                    if(getName().equals("抽奖箱1")){
                        System.out.println("抽奖箱1总共产生了"+index1+"个奖项,分别是:");
                        int sum=0;
                        int max=0;
                        for (int i:prizes1){
                            if(i!=0){
                                sum+=i;
                                max=max>i?max:i;
                                System.out.print(i+" ");
                            }
                        }
                        System.out.println("最高奖项为:"+max+",总计额为"+sum+"元。");

                    }else{
                        System.out.println("抽奖箱2总共产生了"+index2+"个奖项,分别是:");
                        int sum=0;
                        int max=0;
                        for (int i:prizes2){
                            if(i!=0){
                                sum+=i;
                                max=max>i?max:i;
                                System.out.print(i+" ");
                            }
                        }
                        System.out.println("最高奖项为:"+max+",总计额为"+sum+"元。");
                    }
                    break;
                }else{
                    Random r=new Random();
                    int index;
                    while(true){
                        index=r.nextInt(prizes.length);
                        if(flag[index]==false)
                            break;
                    }
                    flag[index]=true;
                    if(getName().equals("抽奖箱1")){
                        prizes1[index1++]=prizes[index];
                    }else{
                        prizes2[index2++]=prizes[index];
                    }
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

Main类:

package exercise6;



public class Main {
    public static void main(String[] args) {
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();
        t1.setName("抽奖箱1");
        t2.setName("抽奖箱2");
        t1.start();
        t2.start();
    }
}

解法二用ArrayList

Thread类

package exercise6itcast;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class MyThread extends Thread{
    ArrayList<Integer> list;
    public MyThread(ArrayList<Integer> list){
        this.list=list;
    }
    static ArrayList<Integer> list1=new ArrayList<Integer>();
    static ArrayList<Integer> list2=new ArrayList<Integer>();
    @Override
    public void run() {
        while (true){
            synchronized (MyThread.class){
                if(list.size()==0){
                    if(getName().equals("抽奖箱1")){
                        System.out.println("抽奖箱1总共产生了"+list1.size()+"个奖项,分别是:");
                        System.out.println(list1+" 最高奖项为:"+Collections.max(list1)+",总计额为"+ list1.stream().reduce(Integer::sum).orElse(0)+"元。");


                    }else{
                        System.out.println("抽奖箱2总共产生了"+list2.size()+"个奖项,分别是:");
                        System.out.println(list2+" 最高奖项为:"+Collections.max(list2)+",总计额为"+ list2.stream().reduce(Integer::sum).orElse(0)+"元。");
                    }
                    break;
                }else{
                    Collections.shuffle(list);
                    int prize=list.remove(0);
                    if(getName().equals("抽奖箱1")){
                        list1.add(prize);
                    }else{
                        list2.add(prize);
                    }
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

Main类:

package exercise6itcast;

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

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> list=new ArrayList<>();
        Collections.addAll(list,100,300,2,800,50,700,200,10,5,80,20,500);
        MyThread t1=new MyThread(list);
        MyThread t2=new MyThread(list);
        t1.setName("抽奖箱1");
        t2.setName("抽奖箱2");
        t1.start();
        t2.start();
    }
}

解法三 改进如果有多个线程的情况

Thread类:

package exercise6itcastImprove;

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

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

    @Override
    public void run() {//因为每个线程都会执行run方法
        ArrayList<Integer> listBox=new ArrayList<Integer>();
        while(true){
            synchronized (MyThread.class){
                if(list.size()==0){
                    System.out.println(getName()+"总共产生了"+listBox.size()+"个奖项,分别是:");
                    System.out.println(listBox+" 最高奖项为:"+ Collections.max(listBox) +",总计额为"+listBox.stream().reduce(Integer::sum).orElse(0)+"元。");
                    break;
                }else{
                    Collections.shuffle(list);
                    int prize=list.remove(0);
                    listBox.add(prize);
                }
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

Main类:

package exercise6itcastImprove;

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

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> list=new ArrayList<Integer>();
        Collections.addAll(list,80, 50, 800, 500, 20, 200, 5,2, 10, 700, 300, 100);
        MyThread t1=new MyThread(list);
        MyThread t2=new MyThread(list);
        MyThread t3=new MyThread(list);
        MyThread t4=new MyThread(list);
        t1.setName("抽奖箱1");
        t2.setName("抽奖箱2");
        t3.setName("抽奖箱3");
        t4.setName("抽奖箱4");
        t1.start();
        t2.start();
        t3.start();
        t4.start();


    }
}

07多线程之间的比较

在06题目的基础上继续完成如下需求:
在此次抽奖过程中,抽奖箱1总共产生了6个奖项,分别为:10,20,100,500,2,300
最高奖项为300元,总计额为932元
在此次抽奖过程中,抽奖箱1总共产生了6个奖项,分别为:5,50,200,800,80,700
最高奖项为800元,总计额为1835元
在此次抽奖过程中,抽奖箱2产生了最大奖项,该奖项金额为800元
(注:和上一题的区别在于最后一句话,要知道哪个抽奖箱产生了最大抽奖金额)
Thread类:

package exercise7;

import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.Callable;

public class MyCallable implements Callable<Integer> {
    ArrayList<Integer> list;
    public MyCallable(ArrayList<Integer> list){
        this.list=list;
    }
    @Override
    public Integer call() throws Exception {
        ArrayList<Integer> boxList=new ArrayList<>();
        while(true){
            synchronized (MyCallable.class){
                if(list.size()==0){
                    System.out.println(Thread.currentThread().getName()+boxList);
                    break;
                }else{
                    Collections.shuffle(list);
                    int prize=list.remove(0);
                    boxList.add(prize);
                }
            }
        }
        if(boxList.size()==0)
            return null;
        return Collections.max(boxList);
    }
}

Main类:

package exercise7;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class Main {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ArrayList<Integer> list=new ArrayList<>();
        Collections.addAll(list,100,500,300,700,800,10,50,20,5,2,80,200);
        MyCallable c=new MyCallable(list);
        FutureTask<Integer> f1=new FutureTask<>(c);
        FutureTask<Integer> f2=new FutureTask<>(c);
        Thread t1=new Thread(f1);
        Thread t2=new Thread(f2);
        t1.setName("抽奖池1");
        t2.setName("抽奖池2");
        t1.start();
        t2.start();
        Integer max1=f1.get();
        Integer max2=f2.get();
        if(max1>max2)
            System.out.println("抽奖箱1产生了最大抽奖金额为"+max1+"元。");
        else
            System.out.println("抽奖箱2产生了最大抽奖金额为"+max2+"元。");

    }
}

你可能感兴趣的:(java,java)