第二课 ConcurrentHashMap锁分段机制

1 HashTable的弊端

传统的HashTable会将哈希表整体锁住,导致原本的并行操作转换成串行化操作,提高了数据的一致性,但是性能很低,由于使用锁的机制,会导致复合操作线程不安全的问题,如:“若不存在则添加”。这种复合操作需要两步操作,首先需要判断是否存在,之后进行添加操作,两个方法均存在锁机制,如果判断是否存在的方法执行权被剥夺,则会产生严重的线程安全问题

2 ConcurrentHashMap锁分段机制

  • Java5.0在java.util.concurrent包中提供了多种并发容器类来改进同步容器的性能。

  • ConcurrentHashMap同步容器类是Java5增加的一个线程安全的哈希表。对与多线程的操作,介于HashMapHashtable之间。内部采用“锁分段”机制替代Hashtable的独占锁。进而提高性能。

  • 此包还提供了设计用于多线程上下文中的Collection实现:ConcurrentHashMapConcurrentSkipListMapConcurrentSkipListSetCopyOnWriteArrayList和CopyOnWriteArraySet

    • 当期望许多线程访问一个给定collection时,ConcurrentHashMap通常优于同步的HashMap,ConcurrentSkipListMap通常优于同步的TreeMap
    • 当期望的读数和遍历远远大于列表的更新数时,CopyOnWriteArrayList优于同步的ArrayList
  • 参考资料:ConcurrentHashMap原理深度分析、锁分段技术

  • 并发读写问题

package JUC;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ConcurrentHashMapTest {
	public static void main(String[] args) {
		ThreadTest3 test3 = new ThreadTest3();
		for (int i = 0; i < 10; i++) {
			new Thread(test3).start();
			// 报错:java.util.ConcurrentModificationException
			// 原因:在线程中,既从list中读取值,又向list中写入值
		}
	}
}

class ThreadTest3 implements Runnable {
	private static List<String> list = new ArrayList<String>();
	static {
		list.add("aa");
		list.add("bb");
		list.add("cc");
	}

	@Override
	public void run() {
		Iterator<String> it = list.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
			list.add("ee");
		}
	}

}
  • 解决办法:使用CopyOnWriteArrayList(写入并复制:每次写入时先进行复制,添加操作时效率低,适合多迭代的操作),用法与普通的List相同
package JUC;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class ConcurrentHashMapTest {
	public static void main(String[] args) {
		ThreadTest4 test4 = new ThreadTest4();
		for (int i = 0; i < 10; i++) {
			new Thread(test4).start();
		}
	}
}

class ThreadTest4 implements Runnable {
	private static CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
	static {
		list.add("aa");
		list.add("bb");
		list.add("cc");
	}

	@Override
	public void run() {
		Iterator<String> it = list.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
			list.add("ee");
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值