标题:多线程问题,在同步代码块外为什么不可以遍历集合?
只看楼主
蓄力小绵羊
Rank: 2
等 级:论坛游民
帖 子:26
专家分:14
注 册:2018-4-23
结帖率:0
 问题点数:0 回复次数:7 
多线程问题,在同步代码块外为什么不可以遍历集合?
/*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();//在这里为什么不可以遍历集合?
        
    }
}
搜索更多相关主题的帖子: 遍历 集合 new Thread Map 
2018-04-30 15:34
疯狂的小a
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:39
帖 子:423
专家分:1871
注 册:2018-2-6
得分:0 
程序代码:
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));
        }
    }
}

假如人生没有梦想,和咸鱼有什么区别!
2018-04-30 17:25
蓄力小绵羊
Rank: 2
等 级:论坛游民
帖 子:26
专家分:14
注 册:2018-4-23
得分:0 
为什么加个break就可以啦?
这个程序怎么每次运行都一样啊
结果都是:
李四送了500件快递,共赚250.0元
张三送了500件快递,共赚250.0元
2018-04-30 20:25
疯狂的小a
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:39
帖 子:423
专家分:1871
注 册:2018-2-6
得分:0 
回复 3楼 蓄力小绵羊
你把1000改成10000试试

假如人生没有梦想,和咸鱼有什么区别!
2018-04-30 20:42
蓄力小绵羊
Rank: 2
等 级:论坛游民
帖 子:26
专家分:14
注 册:2018-4-23
得分:0 
回复 4楼 疯狂的小a
也是一样的。而且时间挺久的
结果还是:
张三送了5000件快递,共赚2500.0元
李四送了5000件快递,共赚2500.0元

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

要是只用一个线程结果是对的
2018-04-30 23:09
疯狂的小a
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:39
帖 子:423
专家分:1871
注 册:2018-2-6
得分:0 
代码没问题的,你是不是哪里复制错了

假如人生没有梦想,和咸鱼有什么区别!
2018-05-01 09:36
tengyuchong
Rank: 1
等 级:新手上路
威 望:1
帖 子:3
专家分:0
注 册:2018-6-4
得分:0 
不加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编辑过]

2018-06-04 16:31



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-486513-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.088833 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved