黑马程序员技术交流社区

标题: 大神帮忙看一下这个多线程的题目 [打印本页]

作者: baoxinyu    时间: 2016-10-6 11:46
标题: 大神帮忙看一下这个多线程的题目
import java.util.ArrayList;
import java.util.Random;

public class kaoshi04 {

        /**
         ** 有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中存放了这些奖项:
         *   10,5,20,50,100,200,500,800,2,80,300
                创建两个线程名称分别为“线程A”,“线程B”,两个线程随机从抽奖池中获取奖项(不能获取到相同的奖项),
                最终只需要打印每个线程获取的奖项及获取奖项的总金额:
                打印格式如下:
                线程A 产生了 10,5,20,50,100,200 的奖项,总计385元
                线程B 产生了 500,800,2,80,300 100 的奖项,总计1782元
         *
         */
        public static void main(String[] args) {

                //定义实现Runnable接口的实现类ChouJiangChi对象
                ArrayList<Integer> list = new ArrayList<>();
                list.add(10);
                list.add(5);
                list.add(20);
                list.add(50);
                list.add(100);
                list.add(200);
                list.add(500);
                list.add(800);
                list.add(2);
                list.add(80);
                list.add(300);
                ChouJiangChi cjc = new ChouJiangChi(list);
                //开启两个线程
                new Thread(cjc,"线程A").start();
                new Thread(cjc,"线程B").start();
        }
}
class ChouJiangChi implements Runnable {
        //定义存放奖项的抽奖池ArrayList
        private ArrayList<Integer> list = new ArrayList<>();
       
        public ChouJiangChi(ArrayList<Integer> list) {
                this.list = list;
        }
        //为什么被注释的这一段代码不对
               
                /*public void run() {
                        // TODO Auto-generated method stub
                        ArrayList<Integer> newList = new ArrayList<>();
                        while (list.size()>0) {
                                synchronized (this) {
                                        int index = new Random().nextInt(list.size());
                                        int i = list.remove(index);
                                        newList.add(i);
                                        try {
                                                Thread.sleep(20);
                                        } catch (Exception e) {
                                                // TODO: handle exception
                                                e.printStackTrace();
                                        }

                                }

                        }*/
       
       
        @Override
        public void run() {
                ArrayList<Integer> newList = new ArrayList<>();
                while(true) {
                        synchronized (this) {
                                if(list.size()<=0)
                                        break;
                                //定义Random对象产生一个随机的索引,既然索引是随机的,对应元素也是随机的
                                int index = new Random().nextInt(list.size());
                                //获取该索引对应的元素
                                int num = list.remove(index);
                                //将抽出的奖项放到newList集合中
                                newList.add(num);
                                try {
                                        Thread.sleep(10);
                                } catch (InterruptedException e) {
                                        e.printStackTrace();
                                }
                        }
                }
                print(Thread.currentThread().getName(),newList);
        }
        //打印newList中的内容
        private void print(String name, ArrayList<Integer> newList) {
                //线程A 产生了 10,5,20,50,100,200 的奖项,总计385元
                StringBuilder sb = new StringBuilder();
                int count = 0;
                sb.append(name+" 产生了 "+"[");
                for(int i = 0;i<newList.size();i++) {
                        count +=newList.get(i);
                        sb.append(newList.get(i));
                        if(i!=newList.size()-1)
                                sb.append(",");                       
                }
                sb.append("]的奖项,总计"+count+"元");
                System.out.println(sb.toString());
        }       
}



作者: Daveweil    时间: 2016-10-6 12:17
有什么问题么?不说有啥问题,看起来没有啥毛病啊

作者: yuanchao    时间: 2016-10-6 12:35
这道题做的不错啊
作者: baoxinyu    时间: 2016-10-6 12:54
Daveweil 发表于 2016-10-6 12:17
有什么问题么?不说有啥问题,看起来没有啥毛病啊

Exception in thread "线程B" java.lang.IllegalArgumentException: n must be positive
线程A 产生了 [800,5,50,200,2]的奖项,总计1057元
        at java.util.Random.nextInt(Random.java:300)
        at test04.ChouJiangChi.run(kaoshi04.java:53)
        at java.lang.Thread.run(Thread.java:744)

作者: baoxinyu    时间: 2016-10-6 12:57
Daveweil 发表于 2016-10-6 12:17
有什么问题么?不说有啥问题,看起来没有啥毛病啊

Exception in thread "线程B" java.lang.IllegalArgumentException: n must be positive
线程A 产生了 [800,5,50,200,2]的奖项,总计1057元
        at java.util.Random.nextInt(Random.java:300)
        at test04.ChouJiangChi.run(kaoshi04.java:53)
        at java.lang.Thread.run(Thread.java:744)

作者: Daveweil    时间: 2016-10-6 14:52
你随机数的生成有问题,我看了一下源码,这里面的数字不能是负数还有0,而你这样写会有0,所以出现异常

作者: baoxinyu    时间: 2016-10-6 16:22
Daveweil 发表于 2016-10-6 14:52
你随机数的生成有问题,我看了一下源码,这里面的数字不能是负数还有0,而你这样写会有0,所以出现异常
...

是while(list.size〉0)出错了

作者: Daveweil    时间: 2016-10-6 16:26
你数没数输出的个数啊?你改这个就导致你输出会是十个

作者: 谢磊    时间: 2016-10-6 19:11
        public static void main(String[] args) {
                Money m1 = new Money();
                Money m2 = new Money();
                m1.setName("线程A");
                m2.setName("线程B");
                m1.start();
                m2.start();               
        }
}
class Money extends Thread{
        Random r = new Random();
//        HashMap<String, Integer> hm = new HashMap<>();
        int[] arr = {10,5,20,50,100,200,500,800,2,80,300};
        int sum = 0;
        static int count = 0;
        public void run(){
               
                while(count <= arr.length){
                        synchronized (Money.class) {                       
                                int index = r.nextInt(arr.length);                                                               
                                sum = sum + arr[index];                                       
                                System.out.println(this.getName() + "获取了 :" + arr[index] + "金额的奖项");
                                count++;
                        }               
                }
                System.out.println(this.getName() + "总计获得-->" + sum);       
        }
作者: 谢磊    时间: 2016-10-6 19:15
大概就这样了,至于怎么保证索引不重复就由你来补充吧,骚年.
作者: baoxinyu    时间: 2016-10-6 19:22
谢磊 发表于 2016-10-6 19:15
大概就这样了,至于怎么保证索引不重复就由你来补充吧,骚年.

好的  谢谢哥

作者: poi1234bnm    时间: 2016-11-7 13:16
确定不用notifyAll()和this.wait()进行线程通信。?




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2