package 第二章.并发下诡异的HashMap; import org.junit.Test; import java.util.HashMap;import java.util.Map;import java.util.concurrent.atomic.AtomicInteger; /** * Created by zzq on 2018/1/19. */public class HashMapMultiThread { static HashMap<String, String> map = new HashMap<String, String>(); static AtomicInteger integer=new AtomicInteger(0); public static class AddThread extends Thread { int start = 0; public AddThread(int start) { this.start = start; } @Override public void run() { for (int i = start; i < 100000; i += 2) { String put = map.put(Integer.toString(i), Integer.toString(i));// System.out.println(map.size()); } } } public static void main(String args[]) throws InterruptedException { Thread thread1 = new Thread(new HashMapMultiThread.AddThread(0)); Thread thread2 = new Thread(new HashMapMultiThread.AddThread(1)); thread1.start(); thread2.start(); thread1.join(); thread2.join(); thread2.join(); thread2.join(); int a=0; for (String i:map.keySet()){ if(!i.equals(map.get(i))){// System.out.println(i); a++; } } System.out.println(map.size()); System.out.println(a); } @Test public void aaa(){ System.out.println(8 & 32); }}
1.实例中我们可以看出1.8为例:(2个线程得到的size 不一定是2个线程数量之和) 每次添加之前,会执行 int i = indexFor(hash, table.length); 获取table的下标值,而 indexFor这个方法中(下面为源码) static int indexFor(int h, int length) { // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2"; return h & (length-1); } 这个函数返回一个值, 作为table的下标 Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE; 并发说明:由于在某一时刻2个线程获取的下标值相同,那么就会造成以上情况。 2.如果jdk使用1.7的情况下,那么程序会造成死锁,死锁的原因,请看下面的分析: 假如有两个线程P1、P2,以及链表 a=》b=》null1、P1先执行,执行完"Entry<K,V> next = e.next;"代码后发生阻塞,或者其他情况不再执行下去,此时e=a,next=b 2、而P2已经执行完整段代码,于是当前的新链表newTable[i]为b=》a=》null 3、P1又继续执行"Entry<K,V> next = e.next;"之后的代码,则执行完"e=next;"后,newTable[i]为a《=》b,则造成回路,while(e!=null)一直死循环
原文地址:https://www.cnblogs.com/anxbb/p/8425474.html
时间: 2024-10-12 20:08:31