将元素并发写入 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。
将元素并发写入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。