同步容器和工具类
1:concurrentHashMap
concurrentHashMap采用的是锁分段技术。
HashTab容器在竞争的并发环境下,效率低下的原因是:所有访问HashTab的线程必须竞争同一把锁,加入容器里面有很多把锁,那么每一把锁都只锁定其中一部分,当多线程并发访问的时候,线程间就不会存在锁竞争。
结构:Segment数组和HashEntry数组结构组成,Segment结构其实和HashMap结构效果一样,是一种数组和链表的结构,一个Segment数组里面包含了一个HashEntry数组。锁是锁着Segment。
2:怎么减少线程的上下文切换
1:CAS算法,采用原子类
2:根据具体任务场景来创建比较合适的线程
3:无锁并发编程,多线程并发使用的时候,会引起上下文切换,所以多线程处理数据时。可以采用一些方法来避免锁。
3:阻塞队列
BlockingQueue是所有的阻塞队列的父接口。具体的实现例子有:
1:LinkedBlockingQueue:链表实现
2:ArrayedBlockingQueue:数组
3:SynchronousQueue:同步队列:一个调用插入方法的线程必须等待另一个线程调用取出方法,队列里面没有容量。
4:PriorityBlockingQueue优先级阻塞队列
5:DelayQueue 延迟队列。
4:同步工具
同步工具主要包括1:CountDownLatch(一次性栅栏)、2:Semaphore(信号量)、3:CyclicBarrier(循环同步栅栏)、4:Exchanger(线程间交换器)和Phaser。
注意,CountDownLatch是一次性的,当条件满足后,它不能再回到初始状态,也不能阻止后续线程了。 如果需要可以使用CyclicBarrier。 每当调用await方法时,内部调用了tryAcquireShared方法,由于state>0,因此调用的线程会阻塞在共享锁的循环框架中。每当调用countDown方法时,内部调用了releaseShared方法,而此方法将会把state的值减1,当state的值为0时,tryAcquireShared中的循环将会唤醒所有等待线程,使之继续运行。由于tryAcquireShared方法中没有修改state值,因此CountDownLatch只能一次性使用,不能循环使用。
CyclicBarrier得到了一个parties数值,它代表参与的线程数量,以及一个Runnable的实例,它代表被激发的事件。每当有线程调用await时,parties减1。若此时parties大于0,线程就在Condition处阻塞,若parties等于0,则此Condition会调用signalAll释放所有等待线程,并触发事件,同时将parties复原。因此所有的线程又进入下一轮循环。
Semaphore:在多个任务争夺几个有限的共享资源时使用。调用acquire方法获取一个许可,成功获取的线程继续执行,否则就阻塞;调用release方法释放一个许可。每当有空余的许可时,阻塞的线程和其他线程可竞争许可
网友评论