线程死锁_hashMap参数

多线程

1、模拟一个线程死锁

package com.m.sort;



public class Test2 {
    private static final Object obj1 = new Object();
    private static final Object obj2 = new Object();
    public static void main(String[] args) {
        new Thread(()->{
            synchronized (obj1){
                try {
                    Thread.sleep(1000);
                    new A().test(obj1);
                    synchronized (obj2){
                        new A().test(obj2);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();

//解决死锁        
//        try {
//            Thread.sleep(2000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        /*
            A:java.lang.Object@4f7a3a41
            A:java.lang.Object@41bdddde
            B:java.lang.Object@41bdddde
            B:java.lang.Object@4f7a3a41
         */
        new Thread(()->{
            synchronized (obj2){
                new A().test(obj2);
                synchronized (obj1){
                    new A().test(obj1);
                }
            }
        },"B").start();
    }
}

class A{
    void test(Object obj){
        System.out.println(Thread.currentThread().getName()+":"+obj.toString());
    }
}

2、HashMap的put()与get();

  • 根据6大参数说明put()或者putAll()干了什么

    1、16表示数组的默认长度,使用时创建,与StringBuilder对比,StringBuilder是构造函数创建默认长度
    
    2、1<<30就是2是30次方,数组的最大长度
    
    3、0.75f是负载因子,数组要不要扩容,就看当前数组的长度n*0.75f,在数组添加元素时,当前的Entry<K,V>的size是否大于threshold = loadFactor*当前数组的容量,是就resize()[例如:从16扩容到32]
    
    
    if (++size > threshold)
      		resize();	
            
    
    
    4、8 是 链表长度到达8之后转红黑树的临界条件,在数组长度大于64的基础上生效。
    
    5、6 是 红黑叔转链表的临界条件
    
    6、64是最小树容量,就是链表在转成红黑树时,如果数组的长度<64,就优先扩容数组resize(),本次不转红黑树了
    
    /**
     * The default initial capacity - MUST be a power of two.
     */
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

    /**
     * The maximum capacity, used if a higher value is implicitly specified
     * by either of the constructors with arguments.
     * MUST be a power of two <= 1<<30.
     */
    static final int MAXIMUM_CAPACITY = 1 << 30;

    /**
     * The load factor used when none specified in constructor.
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    /**
     * The bin count threshold for using a tree rather than list for a
     * bin.  Bins are converted to trees when adding an element to a
     * bin with at least this many nodes. The value must be greater
     * than 2 and should be at least 8 to mesh with assumptions in
     * tree removal about conversion back to plain bins upon
     * shrinkage.
     */
    static final int TREEIFY_THRESHOLD = 8;

    /**
     * The bin count threshold for untreeifying a (split) bin during a
     * resize operation. Should be less than TREEIFY_THRESHOLD, and at
     * most 6 to mesh with shrinkage detection under removal.
     */
    static final int UNTREEIFY_THRESHOLD = 6;

    /**
     * The smallest table capacity for which bins may be treeified.
     * (Otherwise the table is resized if too many nodes in a bin.)
     * Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts
     * between resizing and treeification thresholds.
     */
    static final int MIN_TREEIFY_CAPACITY = 64;

3、Collections.synchronizedMap(new HashMap<String,Object>());

1、这个方法主要是对堆当中的new HashMap的
1、final是线程安全类
2、synchronized(this)代码块处理

public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
    return new SynchronizedMap<>(m);
}

    /**
     * @serial include
     */
private static class SynchronizedMap<K,V>
    implements Map<K,V>, Serializable {
    private static final long serialVersionUID = 1978198479659022715L;

    private final Map<K,V> m;     // Backing Map
    final Object      mutex;        // Object on which to synchronize

    SynchronizedMap(Map<K,V> m) {
        this.m = Objects.requireNonNull(m);
        mutex = this;
    }

    SynchronizedMap(Map<K,V> m, Object mutex) {
        this.m = m;
        this.mutex = mutex;
    }

    public V get(Object key) {
        synchronized (mutex) {return m.get(key);}
    }

    public V put(K key, V value) {
        synchronized (mutex) {return m.put(key, value);}
    }

计数排序


public static void countSort(int [] arr) {
    //1、找到数组最大值
    int max = Integer.MIN_VALUE;
    for(int i:arr){
        if(i > max){
            max = i;
        }
    }
    int [] count = new int[max+1];
    //对arr [] 进行操作
    for(int i = 0;i<arr.length;i++){
        count[arr[i]]++;
    }

    int [] sorted = new int[arr.length];
    int index = 0;
    //[0, 1, 1, 0, 0, 0, 2, 1]
    for(int i = 0;i<count.length;i++){
        for (int j = 0; j < count[i]; j++) {
            sorted[index++] = i;
        }
    }
    System.out.println(Arrays.toString(sorted));
}

下一回发个redis,RPC的模拟的小项目,底层是网络编程的套接字,主要是心跳检测机制的模拟。

ConcurrentHashMap的原理机制与HasnMap大差不差,不同的是前者的内部锁机制,内部是分段加锁,锁的粒度更细了,没有对整个方法加锁的操作。

原文地址:https://www.cnblogs.com/k-class/p/14193266.html