目录
ConcurrentHashMap
一、主程序
二、元素类
三、填充任务类
四、执行结果
实现ConcurrentMap接口,提供线程安全和保证原子性的全部操作。
package xyz.jangle.thread.test.n7_7.concurrenthashmap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
/**
* 7.7、线程安全的HashMap(ConcurrentHashMap)
*
* @author jangle
* @email [email protected]
* @time 2020年9月15日 下午5:20:15
*
*/
public class M {
public static void main(String[] args) {
var userHash = new ConcurrentHashMap>();
var hashFiller = new HashFiller(userHash);
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++) {
threads[i] = new Thread(hashFiller);
threads[i].start();
}
for (int i = 0; i < threads.length; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Size:" + userHash.size());
// 用10个并发线程打印map信息
userHash.forEach(10, (k, v) -> System.out.println(Thread.currentThread().getName() + ":" + k + ":" + v.size()));
// 用10个并发线程打印map信息
userHash.forEachEntry(10, entry -> System.out
.println(Thread.currentThread().getName() + ":" + entry.getKey() + ":" + entry.getValue().size()));
// 用10个并发线程查找元素
Operation search = userHash.search(10, (k, v) -> {
for (Operation o : v) {
if (o.getOperation().endsWith("1")) {
return o;
}
}
return null;
});
System.out.println("查找到结尾为1的元素" + search.getUser() + "," + search.getOperation() + "," + search.getTime());
// 查找value列表大于10的user。
ConcurrentLinkedDeque search2 = userHash.search(10, (k, v) -> {
if (v.size() > 10) {
return v;
}
return null;
});
System.out.println("查找到长度大于10的元素:" + search2.getFirst().getUser() + ",size:" + search2.size());
// 计算散列里面的value列表总值
Integer totalSize = userHash.reduce(10, (k, v) -> v.size(), (n1,n2) -> n1+n2);
System.out.println("散列里value列表总值:"+totalSize);
}
}
package xyz.jangle.thread.test.n7_7.concurrenthashmap;
import java.util.Date;
/**
* 元素类
*
* @author jangle
* @email [email protected]
* @time 2020年9月15日 下午5:33:37
*
*/
public class Operation {
private String user, operation;
private Date time;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
}
package xyz.jangle.thread.test.n7_7.concurrenthashmap;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
/**
* @author jangle
* @email [email protected]
* @time 2020年9月15日 下午5:34:57
*
*/
public class HashFiller implements Runnable {
private ConcurrentHashMap> userHash;
public HashFiller(ConcurrentHashMap> userHash) {
this.userHash = userHash;
}
@Override
public void run() {
var randomGenerator = new Random();
for (int i = 0; i < 100; i++) {
var operation = new Operation();
String user = "USER" + randomGenerator.nextInt(100);
operation.setUser(user);
String action = "OP" + randomGenerator.nextInt(10);
operation.setOperation(action);
operation.setTime(new Date());
// 存入map。
addOperationToHash(userHash, operation);
}
}
/**
* 将operation进行归类,通过user值进行分类到指定的Queue中。由map管理这些Queue。
*
* @author jangle
* @time 2020年9月15日 下午5:45:17
* @param userHash
* @param operation
*/
private void addOperationToHash(ConcurrentHashMap> userHash,
Operation operation) {
// 这个computeIfAbsent是个并发操作,具有原子性,防止并发时的丢失与冲突
ConcurrentLinkedDeque opList = userHash.computeIfAbsent(operation.getUser(),
user -> new ConcurrentLinkedDeque<>());
opList.add(operation);
}
}
Size:100
main:USER58:16
main:USER0:9
main:USER59:4
main:USER56:11
main:USER1:9
main:USER57:4
ForkJoinPool.commonPool-worker-3:USER18:12
main:USER2:11
ForkJoinPool.commonPool-worker-9:USER49:11
ForkJoinPool.commonPool-worker-3:USER19:5
ForkJoinPool.commonPool-worker-3:USER16:7
ForkJoinPool.commonPool-worker-15:USER14:21
ForkJoinPool.commonPool-worker-15:USER15:12
ForkJoinPool.commonPool-worker-11:USER89:13
ForkJoinPool.commonPool-worker-7:USER38:13
main:USER54:5
main:USER55:13
main:USER52:8
main:USER53:7
ForkJoinPool.commonPool-worker-7:USER39:12
ForkJoinPool.commonPool-worker-13:USER29:13
ForkJoinPool.commonPool-worker-13:USER27:20
ForkJoinPool.commonPool-worker-11:USER87:18
ForkJoinPool.commonPool-worker-15:USER12:11
ForkJoinPool.commonPool-worker-9:USER47:11
ForkJoinPool.commonPool-worker-5:USER78:15
ForkJoinPool.commonPool-worker-3:USER17:9
ForkJoinPool.commonPool-worker-5:USER79:6
ForkJoinPool.commonPool-worker-9:USER48:5
ForkJoinPool.commonPool-worker-15:USER13:6
ForkJoinPool.commonPool-worker-11:USER88:15
ForkJoinPool.commonPool-worker-13:USER28:4
ForkJoinPool.commonPool-worker-7:USER36:20
main:USER7:6
ForkJoinPool.commonPool-worker-13:USER69:14
ForkJoinPool.commonPool-worker-7:USER37:9
ForkJoinPool.commonPool-worker-11:USER85:12
ForkJoinPool.commonPool-worker-15:USER98:12
ForkJoinPool.commonPool-worker-9:USER45:16
ForkJoinPool.commonPool-worker-5:USER76:11
ForkJoinPool.commonPool-worker-3:USER25:7
ForkJoinPool.commonPool-worker-5:USER77:11
ForkJoinPool.commonPool-worker-9:USER46:9
ForkJoinPool.commonPool-worker-15:USER10:12
ForkJoinPool.commonPool-worker-11:USER86:8
ForkJoinPool.commonPool-worker-7:USER34:5
ForkJoinPool.commonPool-worker-13:USER67:10
main:USER50:3
ForkJoinPool.commonPool-worker-13:USER68:13
ForkJoinPool.commonPool-worker-13:USER65:13
ForkJoinPool.commonPool-worker-7:USER35:4
ForkJoinPool.commonPool-worker-11:USER83:5
ForkJoinPool.commonPool-worker-11:USER84:8
ForkJoinPool.commonPool-worker-11:USER81:14
ForkJoinPool.commonPool-worker-11:USER82:5
ForkJoinPool.commonPool-worker-15:USER99:7
ForkJoinPool.commonPool-worker-9:USER43:9
ForkJoinPool.commonPool-worker-5:USER74:12
ForkJoinPool.commonPool-worker-5:USER75:7
ForkJoinPool.commonPool-worker-3:USER26:4
ForkJoinPool.commonPool-worker-5:USER72:7
ForkJoinPool.commonPool-worker-5:USER73:12
ForkJoinPool.commonPool-worker-5:USER70:13
ForkJoinPool.commonPool-worker-9:USER44:9
ForkJoinPool.commonPool-worker-15:USER11:10
ForkJoinPool.commonPool-worker-15:USER96:13
ForkJoinPool.commonPool-worker-15:USER97:10
ForkJoinPool.commonPool-worker-15:USER94:12
ForkJoinPool.commonPool-worker-11:USER80:11
ForkJoinPool.commonPool-worker-7:USER32:5
ForkJoinPool.commonPool-worker-13:USER66:17
main:USER51:8
ForkJoinPool.commonPool-worker-13:USER63:12
ForkJoinPool.commonPool-worker-7:USER33:8
ForkJoinPool.commonPool-worker-7:USER30:9
ForkJoinPool.commonPool-worker-15:USER95:6
ForkJoinPool.commonPool-worker-9:USER41:5
ForkJoinPool.commonPool-worker-9:USER42:13
ForkJoinPool.commonPool-worker-5:USER71:9
ForkJoinPool.commonPool-worker-3:USER23:10
ForkJoinPool.commonPool-worker-9:USER40:8
ForkJoinPool.commonPool-worker-15:USER92:8
ForkJoinPool.commonPool-worker-7:USER31:13
ForkJoinPool.commonPool-worker-13:USER64:7
main:USER8:8
main:USER9:12
main:USER3:9
main:USER4:11
ForkJoinPool.commonPool-worker-13:USER61:8
ForkJoinPool.commonPool-worker-15:USER93:5
ForkJoinPool.commonPool-worker-15:USER90:10
ForkJoinPool.commonPool-worker-3:USER24:8
ForkJoinPool.commonPool-worker-15:USER91:9
ForkJoinPool.commonPool-worker-13:USER62:10
main:USER5:13
main:USER6:12
ForkJoinPool.commonPool-worker-13:USER60:18
ForkJoinPool.commonPool-worker-3:USER21:8
ForkJoinPool.commonPool-worker-3:USER22:16
ForkJoinPool.commonPool-worker-3:USER20:6
main:USER58:16
ForkJoinPool.commonPool-worker-5:USER89:13
main:USER0:9
ForkJoinPool.commonPool-worker-11:USER29:13
ForkJoinPool.commonPool-worker-9:USER14:21
ForkJoinPool.commonPool-worker-3:USER18:12
ForkJoinPool.commonPool-worker-15:USER38:13
ForkJoinPool.commonPool-worker-13:USER78:15
ForkJoinPool.commonPool-worker-7:USER69:14
ForkJoinPool.commonPool-worker-13:USER79:6
ForkJoinPool.commonPool-worker-15:USER39:12
ForkJoinPool.commonPool-worker-3:USER19:5
ForkJoinPool.commonPool-worker-9:USER15:12
ForkJoinPool.commonPool-worker-9:USER12:11
ForkJoinPool.commonPool-worker-11:USER27:20
main:USER59:4
main:USER56:11
ForkJoinPool.commonPool-worker-5:USER87:18
main:USER1:9
ForkJoinPool.commonPool-worker-11:USER28:4
ForkJoinPool.commonPool-worker-11:USER25:7
ForkJoinPool.commonPool-worker-9:USER13:6
ForkJoinPool.commonPool-worker-3:USER16:7
ForkJoinPool.commonPool-worker-3:USER17:9
ForkJoinPool.commonPool-worker-15:USER36:20
ForkJoinPool.commonPool-worker-13:USER76:11
ForkJoinPool.commonPool-worker-7:USER67:10
ForkJoinPool.commonPool-worker-3:USER49:11
ForkJoinPool.commonPool-worker-3:USER47:11
ForkJoinPool.commonPool-worker-13:USER77:11
ForkJoinPool.commonPool-worker-15:USER37:9
ForkJoinPool.commonPool-worker-9:USER98:12
ForkJoinPool.commonPool-worker-11:USER26:4
main:USER57:4
ForkJoinPool.commonPool-worker-5:USER88:15
main:USER2:11
ForkJoinPool.commonPool-worker-11:USER23:10
ForkJoinPool.commonPool-worker-9:USER10:12
ForkJoinPool.commonPool-worker-15:USER34:5
ForkJoinPool.commonPool-worker-13:USER74:12
ForkJoinPool.commonPool-worker-3:USER48:5
ForkJoinPool.commonPool-worker-7:USER68:13
ForkJoinPool.commonPool-worker-3:USER45:16
ForkJoinPool.commonPool-worker-13:USER75:7
ForkJoinPool.commonPool-worker-15:USER35:4
ForkJoinPool.commonPool-worker-9:USER99:7
ForkJoinPool.commonPool-worker-11:USER24:8
main:USER54:5
ForkJoinPool.commonPool-worker-5:USER85:12
main:USER55:13
ForkJoinPool.commonPool-worker-11:USER21:8
ForkJoinPool.commonPool-worker-9:USER11:10
ForkJoinPool.commonPool-worker-15:USER32:5
ForkJoinPool.commonPool-worker-13:USER72:7
ForkJoinPool.commonPool-worker-3:USER46:9
ForkJoinPool.commonPool-worker-7:USER65:13
ForkJoinPool.commonPool-worker-3:USER43:9
ForkJoinPool.commonPool-worker-13:USER73:12
ForkJoinPool.commonPool-worker-15:USER33:8
ForkJoinPool.commonPool-worker-9:USER96:13
ForkJoinPool.commonPool-worker-11:USER22:16
main:USER52:8
ForkJoinPool.commonPool-worker-5:USER86:8
main:USER53:7
ForkJoinPool.commonPool-worker-11:USER20:6
ForkJoinPool.commonPool-worker-9:USER97:10
ForkJoinPool.commonPool-worker-15:USER30:9
ForkJoinPool.commonPool-worker-13:USER70:13
ForkJoinPool.commonPool-worker-3:USER44:9
ForkJoinPool.commonPool-worker-7:USER66:17
ForkJoinPool.commonPool-worker-3:USER41:5
ForkJoinPool.commonPool-worker-13:USER71:9
ForkJoinPool.commonPool-worker-15:USER31:13
ForkJoinPool.commonPool-worker-9:USER94:12
main:USER7:6
ForkJoinPool.commonPool-worker-5:USER83:5
main:USER50:3
ForkJoinPool.commonPool-worker-9:USER95:6
ForkJoinPool.commonPool-worker-3:USER42:13
ForkJoinPool.commonPool-worker-7:USER63:12
ForkJoinPool.commonPool-worker-3:USER40:8
ForkJoinPool.commonPool-worker-9:USER92:8
main:USER51:8
ForkJoinPool.commonPool-worker-5:USER84:8
main:USER8:8
ForkJoinPool.commonPool-worker-9:USER93:5
ForkJoinPool.commonPool-worker-7:USER64:7
ForkJoinPool.commonPool-worker-9:USER90:10
main:USER9:12
ForkJoinPool.commonPool-worker-5:USER81:14
main:USER3:9
ForkJoinPool.commonPool-worker-9:USER91:9
ForkJoinPool.commonPool-worker-7:USER61:8
main:USER4:11
ForkJoinPool.commonPool-worker-5:USER82:5
main:USER5:13
ForkJoinPool.commonPool-worker-7:USER62:10
main:USER6:12
ForkJoinPool.commonPool-worker-5:USER80:11
ForkJoinPool.commonPool-worker-7:USER60:18
查找到结尾为1的元素USER89,OP1,Tue Sep 15 18:28:53 CST 2020
查找到长度大于10的元素:USER58,size:16
散列里value列表总值:1000