《Java测试》关于Map遍历移除在多线程下的测试

来源:互联网 发布:深圳申请软件著作权 编辑:程序博客网 时间:2024/06/06 00:50
    1.在java 中,for-each只适用于遍历,当要对集合进行操作的时候,就会导致错误,在java源码中可以看到相关的原因,因为对集合的操作都会导致modCount++,当迭代的时候回检查这个值。所以在**移除遍历移除map中的元素时就不能用迭代器**。

所以,就需要for循环进行遍历,大致是这样的

            Set<String> setKeys = maps.keySet();            //做移除时不能使用迭代器               Object[] keys = setKeys.toArray();            for (int i = 0; i < keys.length; i++) {                int value = maps.get(keys[i]);                System.out.println(" 当前移除数据:\t"+ value);                maps.remove(keys[i]);            }

但是我用的时候在考虑,将set转换成数组的时候,是否仍是之前map的Key的引用,还是新的数组对象,因为我要在多线程时使用这个集合,就看是否数组中的key是否会随着其他线程插入数据而不一致,这时我还未看(toArray的实现源码)。

下面是测试代码,主线程移除数据,子线程添加数据:

public class ThreadMap {    private Map<String, Integer> maps = new HashMap<>();    public static void main(String[] args) {        new ThreadMap().test1();    }    public void test1(){        for (int i = 0; i < 20; i++) {            maps.put(i+"", i);        }        new AddNumThread().start();        while(true){            Set<String> setKeys = maps.keySet();            //做移除时不能使用迭代器               Object[] keys = setKeys.toArray();            for (int i = 0; i < keys.length; i++) {                int value = maps.get(keys[i]);                System.out.println(" 当前移除数据:\t"+ value);                maps.remove(keys[i]);            }            try {                Thread.sleep(1500);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    //子线程    class AddNumThread extends Thread{        @Override        public void run() {            int number = 1000;            while(true){                for (int i = 0; i < 10; i++) {                    System.out.println(" 当前放入数据:"+ number);                    maps.put(""+number,number);                    number++ ;                }                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }}

测试结果:
这里写图片描述

可以看到子线程先放入 1000,但主线程在移除的时候并没有这个数据,将其移除,而是只移除了预先放入的20个数据。就表明这样写是可以的,转换成数组相当于只保存了当前的版本集合,移除时只作用在当前的时间点。获取时可能需要判断NULL。

0 0
原创粉丝点击