大家好,又见面了,我是你们的朋友全栈君。
SynchronousQueue是一个没有容量的队列,它的put操作和take操作之间是相互依赖的,即put操作必须在take操作准备好时才能将元素“推”过去,反之take操作也必须在put操作准备推元素的时候才能获取到元素。有人可能会说只有1个容量大小的BlockingQueue也能实现该操作,但是它们之间有着本质的不同:
1、SynchronousQueue在put时,如果另一个线程没有执行take操作,put线程会一直阻塞;而BlockingQueue在put一个元素时,第一次是不会阻塞的,只有第二次因为容量满了put操作才阻塞,而SynchronousQueue在第一次就阻塞;
2、从第1点就可以看出SynchronousQueue容量为0,而BlockingQueue至少有容纳1个元素的空间。
应用场景:假设某资源从硬盘加载需要较长时间,而且资源会不定期的更新,一旦更新后在内存中会产生新的资源副本,老的资源必须及时释放,否则随着时间累积最终内存会溢出。
1、作为客户端在使用资源的时候是不能够每次打开资源然后在关闭的,那样导致频繁从硬盘加载并释放,虽然能够保证资源及时更新,但是效率低下。
2、容易想到的大概方法是系统在启动时加载资源,这样客户端可以保证能获取到资源,然后后台起一个线程定期从磁盘加载保证资源得到更新,同时发布出去使得客户端能获取到资源句柄,并且将老的资源关闭。但是关闭的时候又要保证客户端没有正在使用该资源,这是最关键的限制条件。先给出一种实现思路:
1、系统启动时预先加载资源,客户端在第一次获取资源时可以直接获取,避免了第一次加载所耗的时间。
2、新建一个更新线程从磁盘中加载资源并放入到SynchronousQueue中,此时由于客户端正在使用资源于是在第二次获取资源前更新线程会一直阻塞。这样的好处是:更新线程不会频繁从磁盘加载节约了资源,并且还保证了每次加载时,客户端能获取到最新一次加载的资源(可能包含更新,也可能只是新的副本)。
3、当客户端第二次获取资源时,需要将原先的资源设置为老资源,并让更新线程去关闭。这样的好处是由于资源的释放可能是耗时的,那么客户端可以快速获取资源。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/152124.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...