当前位置:网站首页>How to use concurrentlinkedqueue as a cache queue
How to use concurrentlinkedqueue as a cache queue
2022-07-04 21:33:00 【Xiaoqu classmate】
In the project , We may use queues , that ConcurrentLinkedQueue, Is an essential . For multithreaded environments , Want to achieve thread safety , Or lock it yourself , Or use thread safe queues -------ConcurrentLinkedQueue.
Let's see how to use it ConcurrentLinkedQueue How to build a cache queue .
package server.utils;
import java.util.concurrent.ConcurrentLinkedQueue;
public class QueueUtils {
// User cache queue
private static final ConcurrentLinkedQueue<String> queueCache = new ConcurrentLinkedQueue<>();
private int rank;
// The team
public void offer(String userId) {
queueCache.offer(userId);
}
// Determine whether an element exists
public boolean isExist(String userId) {
if (queueCache.contains(userId)) {
return true;
}
return false;
}
// Get ranking
public int getRank(String userId) {
if (isExist(userId)) {
for (String id : queueCache) {
if (id.equals(userId)) {
break;
}
rank++;
}
System.out.printf("rank Ranked as " + rank);
return rank;
} else {
// If not, join the end of the team
offer(userId);
rank = queueCache.size() + 1;
System.out.printf(" If users are not included, join the end of the team " + rank);
return rank;
}
}
public static void main(String[] args) {
for (int i = 1; i < 6; i++) {
new QueueUtils().getRank("1" + i);
}
new QueueUtils().getRank("15");
}
}
Summarize the three common methods :peak(),poll() Method ,offer() Method
peak() Method :
The function of this method is to get the elements of the queue header , Get only, don't remove , Pay attention to this method and the following poll The difference between methods !
public E peek() {
//[1]goto sign
restartFromHead:
for (;;) {
for (Node<E> h = head, p = h, q;;) {
//[2]
E item = p.item;
//[3]
if (item != null || (q = p.next) == null) {
updateHead(h, p);
return item;
}
//[4]
else if (p == q)
continue restartFromHead;
else//[5]
p = q;
}
}
}
final void updateHead(Node<E> h, Node<E> p) {
if (h != p && casHead(h, p)) {
h.lazySetNext(h);
}
poll() Method :
This method is to get the node of the header , Return if the queue is empty null;
public E poll() {
// This is actually a goto The tag , For jumping out for loop
restartFromHead:
//[1]
for (;;) {
for (Node<E> h = head, p = h, q;;) {
E item = p.item;
//[2] If the value stored in the current node is not empty , be CAS Set to null
if (item != null && p.casItem(item, null)) {
//[3]CAS Update the location of the header node after success
if (p != h)
updateHead(h, ((q = p.next) != null) ? q : p);
return item;
}
//[4] The current queue is empty , Just go back to null
else if ((q = p.next) == null) {
updateHead(h, p);
return null;
}
//[5] The current node is the same as the next node , Description node self reference , Then find the head node again
else if (p == q)
continue restartFromHead;
//[6]
else
p = q;
}
}
}
final void updateHead(Node<E> h, Node<E> p) {
if (h != p && casHead(h, p))
h.lazySetNext(h);
}
offer() Method :
The function of this method is to add a node at the end of the queue , If the parameter passed is null, Throw a null pointer exception , Otherwise, because the queue is unbounded , This method will always return true, And this method uses CAS algorithmic , therefore Will not block threads ;
// Add a node at the end of the queue
public boolean offer(E e) {
// If e It's empty , Then throw a null pointer exception
checkNotNull(e);
// Encapsulate the incoming elements into a node ,Node In the constructor UNSAFE.putObject(this, itemOffset, item) hold e Assigned to item
final Node<E> newNode = new Node<E>(e);
//[1]
// there for The loop starts at the last node
for (Node<E> t = tail, p = t;;) {
Node<E> q = p.next;
//[2] If q by null, explain p It's the last node
if (q == null) {
//[3]CAS to update : If p The next node of the node is null, Just update the write node to newNode
if (p.casNext(null, newNode)) {
//[4]CAS success , But at this moment p==t, So I won't enter here if Inside , Go straight back to true
// So when will you come here ? In fact, another thread is also calling offer Method time , Will enter here
if (p != t)
casTail(t, newNode);
return true;
}
}
else if (p == q) //[5]
p = (t != (t = tail)) ? t : head;
else //[6]
p = (p != t && t != (t = tail)) ? t : q;
}
}
summary :
In fact, there are still several methods left unsaid , But I feel it's easier, so I don't waste space , You can have a look if you are interested :size Method is used to calculate the number of nodes in the queue , But because there is no lock , Inaccurate under concurrent conditions ;remove Method to delete a node , In fact, it is traversal and then use equals Methods to compare item It is not the same , Only if there are multiple qualified nodes, only the first one will be deleted , Then return true, Otherwise return to false;contains Method to determine whether the queue contains the specified item The node of , That's traversal , be prone to ;
The hardest part is offer Methods and poll Method ,offer The method is to add nodes at the end of the queue , and poll Is to get the header node , And delete the first real queue node ( Be careful , There are two kinds of nodes , One is sentinel node , One is the node that actually stores data ), I also simply said poll Methods and peek Differences in methods , The latter is just getting , Instead of deleting !
边栏推荐
- Solution of 5g unstable 5g signal often dropped in NetWare r7000 Merlin system
- 杰理之AD 系列 MIDI 功能说明【篇】
- Detailed explanation of multi-mode input event distribution mechanism
- Google colab踩坑
- PS vertical English and digital text how to change direction (vertical display)
- 插入排序,选择排序,冒泡排序
- Y56. Chapter III kubernetes from entry to proficiency -- business image version upgrade and rollback (29)
- Redis:Redis配置文件相关配置、Redis的持久化
- 【Try to Hack】宽字节注入
- 2021 CCPC 哈尔滨 I. Power and Zero(二进制 + 思维)
猜你喜欢
Hwinfo hardware detection tool v7.26 green version
Analysis of maker education technology in the Internet Era
每日一题-LeetCode556-下一个更大元素III-字符串-双指针-next_permutation
如何使用ConcurrentLinkedQueue做一个缓存队列
【C语言】符号的深度理解
【微信小程序】协同工作与发布
数十亿公民信息遭泄漏!公有云上的数据安全还有“救”吗?
[C language] deep understanding of symbols
[weekly translation go] how to code in go series articles are online!!
巅峰不止,继续奋斗!城链科技数字峰会于重庆隆重举行
随机推荐
刘锦程荣获2022年度中国电商行业创新人物奖
Jerry's ad series MIDI function description [chapter]
Roast B station charges, is it because it has no money?
[weekly translation go] how to code in go series articles are online!!
应用实践 | 蜀海供应链基于 Apache Doris 的数据中台建设
Daily question -leetcode1200- minimum absolute difference - array - sort
redis RDB AOF
2021 CCPC Harbin B. magical subsequence (thinking question)
Day24: file system
redis03——Redis的网络配置与心跳机制
At the right time, the Guangzhou station of the city chain science and Technology Strategy Summit was successfully held
Minidom module writes and parses XML
【Try to Hack】宽字节注入
[wechat applet] collaborative work and release
CAD中能显示打印不显示
Jerry's ad series MIDI function description [chapter]
Why does invariant mode improve performance
Delphi SOAP WebService 服务器端多个 SoapDataModule 实现相同的接口方法,接口继承
Redis transaction
吐槽 B 站收费,是怪它没钱么?