JDK并发包详细总结(4)

public static void main(String[] args){
        final int N = 5;
        Thread[] allSoldier = new Thread[N];
        boolean flag = false;
        CyclicBarrier cyclic = new CyclicBarrier(N, new BarrierRun(flag, N));
        // 设置屏障点, 主要为了执行这个方法.
        System.out.println("集合任务!");
        for (int i = 0; i < N; i++) {
            System.out.println("士兵" + i + " 报到!");
            allSoldier[i] = new Thread(new Soldier(cyclic, "士兵" + i));
            allSoldier[i].start();
        }

}
}

结果

集合任务!
士兵0 报到!
士兵1 报到!
士兵2 报到!
士兵3 报到!
士兵4 报到!
士兵:5个, 集合完毕!
士兵3 任务完成!
士兵1 任务完成!
士兵0 任务完成!
士兵4 任务完成!
士兵2 任务完成!
士兵:5个, 任务完成!

LockSupport

一个线程阻塞工具, 可以在任意位置让线程阻塞.

与suspend()比较, 如果unpark发生在park之前, 并不会导致线程冻结, 也不需要获取锁.

API

1 LockSupport.park();
2 LockSupport.unpark(t1);

中断响应

能够响应中断,但不抛出异常。

中断响应的结果是,park()函数的返回,可以从Thread.interrupted()得到中断标志

public class LockSupportDemo {
    public static Object u = new Object();
    static ChangeObjectThread t1 = new ChangeObjectThread("t1");
    static ChangeObjectThread t2 = new ChangeObjectThread("t2");
    public static class ChangeObjectThread extends Thread {

public ChangeObjectThread(String name) {
            super(name);
        }

@Override
        public void run() {
            synchronized (u) {
                System.out.println("in " + getName());
                LockSupport.park();
            }
        }
    }

public static void main(String[] args) throws InterruptedException {
        t1.start();
        Thread.sleep(100);
        t2.start();
        LockSupport.unpark(t1);
        LockSupport.unpark(t2);
        t1.join();
        t2.join();
    }
}

并发容器 Collections.synchronizedMap

其本质是在读写map操作上都加了锁, 因此不推荐在高并发场景使用.

JDK并发包详细总结

ConcurrentHashMap

支持高并发的HashMap. 通过将一个大的hashmap切割成无数个小的分区hashmap(Segment<K,V>).

执行put的时候把key映射到其中一个小的分区中, 假如有十几个线程, 那么可能就会对应十几个分区.

public V put(K key, V value) {
        ConcurrentHashMap.Segment<K,V> s;
        if (value == null)
            throw new NullPointerException();
        int hash = hash(key);
        int j = (hash >>> segmentShift) & segmentMask;
        // 通过unsafe对j进行偏移来寻找key所对应的分区
        if ((s = (ConcurrentHashMap.Segment<K,V>)UNSAFE.getObject          // nonvolatile; recheck
                (segments, (j << SSHIFT) + SBASE)) == null) //  in ensureSegment
            // 如果分区不存在, 则创建新的分区
            s = ensureSegment(j);
        // kv放到分区中
        return s.put(key, hash, value, false);
    }

Segment.put源码

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8791015b7c833f8476df32253f13fed6.html