将元素并发写入 ConcurrentHashMap 承认元素

Concurrent writing elements into the ConcurrentHashMap admits element

将元素并发写入ConcurrentHashMap 承认元素。要求:写必须在不同的线程中进行。有没有办法利用ConcurrentHashMap的优点,写不阻塞不休眠?

是否有用于从不同线程访问的迭代器的良好代码。或者是否有其他好的变体可以让 ieratian 关注有效最终要求?

public class Task3v2 {

public static void main(String[] args) {
    System.out.println("ConcurrentHashMap : "+timeIt(new ConcurrentHashMap<Integer, String>()));
}

static Iterator<Integer> integerIterator;

static {createIterator();}

private static void createIterator() {
    integerIterator=
    Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toList()).iterator();
}
public static double timer(Runnable block) {
    long start = System.nanoTime();
    try {
        block.run();
    } finally {
        long end = System.nanoTime();
        return(end - start);

    }
}

public static double timeIt(Map<Integer, String> map){
    return timer(
            ()->{
        new Thread(()->{
            fillMap(map);
            System.out.println("invoked");
            readMap(map);
        }).start();
    });
}

private static void fillMap(Map<Integer, String> map){
    int[] index = new int[1];
    String[] tmp = new String[1];
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    for(int i = 0; i< 100; i++){
        index[0] = i;
        tmp[0] = "Name"+i;
        new Thread(()->{
            int a = integerIterator.next();
            System.out.println("a :"+a);
            map.put(a,"Name"+a);
        }
        ).start();
    }
}

private static void readMap(Map<Integer, String> map){
    int[] index2 = new int[1];
    for(int i = 0; i< 100; i++){
        index2[0]=i;
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(()->{
            System.out.println("map.get(index2[0]) :"+map.get(index2[0]));
        }).start();
    }
}

}

最终地图必须通过以下测试:

public class Task3Test {

static ConcurrentHashMap<Integer, String> map;

@BeforeClass
public static void fillMap(){
    map = new ConcurrentHashMap<>();
    timeIt(map);
}


@Test
public void elementPresenceTest(){
    //GIVEN
    //map;

    //WHEN
    List<Integer> actualPresenceList = Stream.iterate(0, i -> i + 1).limit(100)
            .filter(n->(map.entrySet().stream().map(Map.Entry::getKey)
                    .anyMatch(m->(n.equals(m))))).collect(Collectors.toList());
    actualPresenceList.forEach(System.out::println);
    System.out.println("size"+actualPresenceList.size());

    //THEN
    List<Integer>expectedPresenceList = Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toList());
    assertThat(actualPresenceList, Matchers.contains(expectedPresenceList));
}

@Test
public void elementAmountTest() {
    assertThat(map.entrySet(), Matchers.hasSize(100));
}

}

迭代器不能用于并发。解决方案是: 静态队列 integerQueue = Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toCollection(LinkedBlockingQueue::new));

readMap()方法需要一直休眠,为writing方法提供时间。如果在并发环境下添加新元素需要保留任何数据结构,应该使用queue而不是map。