并发编程:并发集合:线程安全的HashMap(ConcurrentHashMap)

目录

ConcurrentHashMap

一、主程序

二、元素类

三、填充任务类

四、执行结果


 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

 

你可能感兴趣的:(并发编程,JavaBase,并发集合,多线程,列表,java,queue)