注册 登录
编程论坛 JAVA论坛

多线程问题,在同步代码块外为什么不可以遍历集合?

蓄力小绵羊 发布于 2018-04-30 15:34, 2813 次点击
/*2、已知飞毛腿代收点共有1000件快递,创建两条线程代表两个快递员(张三,李四)每件快递提成0.5元,
同时开启这两条线程进行送件,每次送件需要耗时5ms;在控制台输出两个快递员分别送了多少件快递以及赚了多少提成(10分)
例如:
    李四送了392件快递,共赚196.0元
    张三送了608件快递,共赚304.0元*/
public class TreadDemo {
    public static void main(String[] args) {
        MyRunnable m = new MyRunnable();
        
        //创建线程对象
        Thread t1 = new Thread(m);
        t1.setName("李四");
        t1.start();
        
        Thread t2 = new Thread(m);
        t2.setName("张三");
        t2.start();
    }
}





class MyRunnable implements Runnable {
    private static final String Map = null;
    int num = 1000;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        double count1 = 0;
        double count2 = 0;
        java.util.Map<String,Double> map = new HashMap<>();
        
        while (true) {
            try {
                Thread.sleep(5);
                synchronized (this) {
                    
                    if (num > 0 && Thread.currentThread().getName().equals("李四")) {
                        count1++; num--;
                        map.put("李四",count1*0.5);
                    }else if(num > 0){
                        count2++; num--;
                        map.put("张三", count2*0.5);
                    }
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        Set<String> keySet = map.keySet();//在这里为什么不可以遍历集合?
        
    }
}
7 回复
#2
疯狂的小a2018-04-30 17:25
程序代码:
package com.xiaoa.test;

import java.util.HashMap;
import java.util.Map;

/*2、已知飞毛腿代收点共有1000件快递,创建两条线程代表两个快递员(张三,李四)每件快递提成0.5元,
同时开启这两条线程进行送件,每次送件需要耗时5ms;在控制台输出两个快递员分别送了多少件快递以及赚了多少提成(10分)
例如:
    李四送了392件快递,共赚196.0元
    张三送了608件快递,共赚304.0元
*/
public class ThreadDemo {
    public static void main(String[] args) {
        MyRunnable m = new MyRunnable();
        // 创建线程对象
        Thread t1 = new Thread(m);
        t1.setName("李四");
        t1.start();
        Thread t2 = new Thread(m);
        t2.setName("张三");
        t2.start();
    }
}

class MyRunnable implements Runnable {
    //private static final String Map = null;
    static int num = 1000;
    static double count1 = 0;
    static double count2 = 0;
   

    @Override
    public void run() {
        Map<String, Double> map = new HashMap<>();
        while (true) {
            try {
                Thread.sleep(5);
                synchronized (this) {
                    if (num > 0 && Thread.currentThread().getName().equals("李四")) {
                        count1++;
                        num--;
                        map.put("李四", count1 * 0.5);
                    } else if (num > 0) {
                        count2++;
                        num--;
                        map.put("张三", count2 * 0.5);
                    }else {
                        break;
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //Set<String> keySet = map.keySet();// 在这里为什么不可以遍历集合?
        for(String key:map.keySet()) {
            System.out.println(key+" : "+map.get(key));
        }
    }
}
#3
蓄力小绵羊2018-04-30 20:25
为什么加个break就可以啦?
这个程序怎么每次运行都一样啊
结果都是:
李四送了500件快递,共赚250.0元
张三送了500件快递,共赚250.0元
#4
疯狂的小a2018-04-30 20:42
回复 3楼 蓄力小绵羊
你把1000改成10000试试
#5
蓄力小绵羊2018-04-30 23:09
回复 4楼 疯狂的小a
也是一样的。而且时间挺久的
结果还是:
张三送了5000件快递,共赚2500.0元
李四送了5000件快递,共赚2500.0元

是不是计数的不能作为共享的啊?

要是只用一个线程结果是对的
#6
疯狂的小a2018-05-01 09:36
代码没问题的,你是不是哪里复制错了
#7
tengyuchong2018-06-04 16:31
不加break while是死循环 循环外写的代码都会编译不通过 楼主sleep的位置应该放在锁里  想要的效果是两人一起送  你现在的效果是一个人送一个人等  送完了下个人再送 可不一样了 写在锁外面的效果是线程每次都是轮流执行的 一个线程进去了另一个在外边排队 以下是代码
    public static void main(String[] args) {
        MyRunnable m = new MyRunnable();

        // 创建线程对象
        Thread t1 = new Thread(m);
        t1.setName("李四");
        t1.start();

        Thread t2 = new Thread(m);
        t2.setName("张三");
        t2.start();
    }
}

class MyRunnable implements Runnable {
    int num = 1000;
   
    @Override
    public void run() {
        double count1 = 0;
        double count2 = 0;
        
        Map<String, Double> map = new HashMap<>();

        while (true) {
            try {
                synchronized (this) {
                    Thread.sleep(5);
                    if (num > 0
                            && Thread.currentThread().getName().equals("李四")) {
                        count1++;
                        num--;
                        map.put("李四", count1 * 0.5);
                    } else if (num > 0) {
                        count2++;
                        num--;
                        map.put("张三", count2 * 0.5);
                    } else {
                        break;
                    }
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        for (String key : map.keySet()) {
            if ("李四".equals("key")) {
                System.out.println(key + " : " + map.get(key) + "  件数: " + map.get(key)/0.5);
            } else {
                System.out.println(key + " : " + map.get(key) + "  件数: " + map.get(key)/0.5);
            }
        }

    }

[此贴子已经被作者于2018-6-4 16:38编辑过]

1