redis主从节点之间会建立一个连接用于复制数据,该连接由从节点收到slave of命令或者cluster replicate(集群模式下)后发起建立到主节点的连接,主从节点均会定时判断该连接是否超时(这个判断过程在replicationCron函数中实现),如果被判断超时,会断开该连接,从节点需要重新建立连接,继续同步数据。
TreeSet,LinkedHashSet以及HashSet之间的区别
原文链接:Difference between TreeSet, LinkedHashSet and HashSet in Java with Example
TreeSet,LinkedHashSet以及HashSet均实现了Set接口,因此他们都遵循Set接口的协议,比如他们都不允许重复的元素。尽管他们都来自同一类型的层次结构,但是他们之间还是有很多区别;理解他们之间的区别非常重要,这样您就可以根据您的需求选择最合适的集合实现。另外,TreeSet和HashSet(或者LinkedHashSet)之间的区别是一个非常流行的Java集合面试题,虽然不如“比较Hashtable和HashMap”或者“比较ArrayList和Vector”这类问题普遍,但是依然出现在各种Java面试中。在这篇文章中,我们将看看HashSet,TreeSet以及LinkedHashSet在各个方面之间的区别,比如元素顺序、性能、是否允许null值等,然后我们会看到在Java中什么时候使用TreeSet、LinkedHashSet、HashSet。
[java1.8源码笔记]SynchronousQueue详解
概述
SynchronousQueue是一种特殊的阻塞队列,不同于LinkedBlockingQueue、ArrayBlockingQueue等阻塞队列,其内部没有任何容量,任何的入队操作都需要等待其他线程的出队操作,反之亦然。任意线程(生产者线程或者消费者线程,生产类型的操作比如put,offer,消费类型的操作比如poll,take)都会等待直到获得数据或者交付完成数据才会返回,一个生产者线程的使命是将线程附着着的数据交付给一个消费者线程,而一个消费者线程则是等待一个生产者线程的数据。它们会在匹配到互斥线程的时候就会做数据交易,比如生产者线程遇到消费者线程时,或者消费者线程遇到生产者线程时,一个生产者线程就会将数据交付给消费者线程,然后共同退出。在java线程池newCachedThreadPool中就使用了这种阻塞队列。
[java1.8源码笔记]ThreadPoolExecutor详解
[java学习笔记]java线程池
[java1.8源码笔记]ReentrantReadWriteLock详解
概述
在并发场景中用于解决线程安全的问题,我们几乎会高频率的使用到独占式锁,通常使用java提供的关键字synchronized或者concurrents包中实现了Lock接口的ReentrantLock。它们都是独占式获取锁,也就是在同一时刻只有一个线程能够获取锁。而在一些业务场景中,大部分只是读数据,写数据很少,如果仅仅是读数据的话并不会影响数据正确性(出现脏读),而如果在这种业务场景下,依然使用独占锁的话,很显然这将是出现性能瓶颈的地方。针对这种读多写少的情况,java还提供了另外一个实现Lock接口的ReentrantReadWriteLock(读写锁)。
ReentrantReadWriteLock,读写锁或者重入读写锁,它维护了一个读锁和一个写锁,它允许同一时刻被多个读线程访问,而此时写线程不能获取到锁,并且当写线程获取到锁时后续的读写线程都将被阻塞不能获取到锁。读写锁保证了写操作对后续的读操作的可见性。同时ReentrantReadWriteLock还支持重入,公平性选择以及锁的降级。