当前位置:网站首页>Websocket multi-threaded sending message error TEXT_PARTIAL_WRITING--Use case of spin lock replacing synchronized exclusive lock
Websocket multi-threaded sending message error TEXT_PARTIAL_WRITING--Use case of spin lock replacing synchronized exclusive lock
2022-08-03 22:25:00 【Master_Shifu_】
1.背景:
websocketWhen using multithreading to push messages,If the same one exists in a large number of messagessessionThe session's sending multiple messages,If two threads get this at the same timesession发送消息就会报错
The remote endpoint was in state [TEXT_PARTIAL_WRITING] which is an invalid stat e for called method
原因就是: handlerA和handlerBIt is possible for both methods to execute simultaneously,当A或者BThe method traverses to a certain onesession并且调用sendMessage发送消息的时候,Another method also happens to be using the samesessionSend another message(同一个sessionMessage sending conflicted,That is, at the same time,Multiple threads to onesocketWrite data conflict),就会报上面的异常.
2.解决办法:
解决方法其实很简单,It is to add a lock when sending a message,(保证一个sessionwill not be called more than once at a time)
/** * 发送信息给指定用户 * @param clientId * @param message * @return */
public static boolean sendMessageToUser(String clientId, TextMessage message) {
WebSocketSession session = socketMap.get(clientId);
if(session==null) {
return false;
}
if (!session.isOpen()) {
return false;
}
try {
synchronized (session) {
session.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
/** * Broadcast the message out * @param message * @return */
public static void sendMessageToAll(TextMessage message) {
for (WebSocketSession session : socketMap.values()) {
if(session==null||!session.isOpen()) {
continue;
}
try {
synchronized (session) {
session.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.存在问题:
根据之前的文章Java并发编程–Implementation and use cases of fair locks
不难发现,The following code block blocks all threads to send in order,This way even multi-threaded callssendMessageToUserIt is also a single-threaded efficient sequential send,Lost the meaning of messages sent by multiple threads,So the above method can solve the problem,But it doesn't substantially improve efficiency
synchronized (session) {
session.sendMessage(message);
}
4.Spin lock solution ideas:
only lock the samesession对象,Let get the same onesessionThreads can only be acquired sequentially,The action of another thread sending a message takes a very short time,Consider simplifying the use of exclusive locksCAS的自旋锁
根据之前的文章Java并发编程–Implementation and use of spinlocks
Spinlocks are implemented using the right lockThread 的nullNand is not empty to determine whether the single-front thread is locked,那我们把session从lock()方法中传入,That can replace the object of the lock withsession,Thereby performing spin locking and unlocking
Spinlock implementation tool class
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.atomic.AtomicReference;
@Slf4j
public class ReentrantSpinLock {
private static AtomicReference<Object> sign = new AtomicReference<>();
public static <T> void lock(T t, boolean reentrantFlag) {
// If the reentrant flag is true, And if the object trying to lock is the same as the object already in the lock,可重入,并加锁成功
if (reentrantFlag && t == sign.get()) {
return;
}
//If the lock is not acquired, it can be spun through CAS
while (!sign.compareAndSet(null, t)) {
// DO nothing
log.info("自旋一会.");
}
}
public static <T> void unlock(T t) {
// 锁的线程和目前的线程相等时,才允许释放锁
if (t == sign.get()) {
sign.compareAndSet(t, null);
}
}
}
其中reentrantFlagIt has been acquired for a certain threadsession,But also need to call othersessionWhether the method is reentrant flag
5.Modified spinlock lock send message code
/** * 发送信息给指定用户 * @param clientId * @param message * @return */
public static boolean sendMessageToUser(String clientId, TextMessage message) {
WebSocketSession session = socketMap.get(clientId);
if(session==null) {
return false;
}
if (!session.isOpen()) {
return false;
}
try {
// Spinlocks guarantee the same for different threadssessionMessages are sent in order
ReentrantSpinLock.lock(session, false);
session.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
} finally {
ReentrantSpinLock.unlock(session);
}
return true;
}
/** * Broadcast the message out * @param message * @return */
public static void sendMessageToAll(TextMessage message) {
for (WebSocketSession session : socketMap.values()) {
if(session==null||!session.isOpen()) {
continue;
}
try {
// Spinlocks guarantee the same for different threadssessionMessages are sent in order
ReentrantSpinLock.lock(session, false);
session.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
} finally {
ReentrantSpinLock.unlock(session);
}
}
}
参考:
The remote endpoint was in state [TEXT_PARTIAL_WRITING] which is an invalid stat e for called method
Java并发编程–Implementation and use cases of fair locks
Java并发编程–Implementation and use of spinlocks
边栏推荐
- navicat 连接 mongodb 报错[13][Unauthorized] command listDatabases requires authentication
- pikachu Over permission 越权
- Optimize the query (work in progress)
- 386. Lexicographical Numbers
- 为什么我们需要回调
- The development status of cloud computing at home and abroad
- 数据一致性:双删为什么要延时?
- encapsulation, package, access modifier, static variable
- 目标检测技术研究现状及发展趋势
- [N1CTF 2018]eating_cms
猜你喜欢
pikachu Over permission
静态文件快速建站
Canvas App中点击图标生成PDF并保存到Dataverse中
Cisco ike2 IPSec configuration
Flutter 桌面探索 | 自定义可拖拽导航栏
2022-08-02 mysql/stonedb慢SQL-Q18-内存使用暴涨分析
Network basic learning series four (network layer, data link layer and some other important protocols or technologies)
【bug】汇总Elipse项目中代码中文乱码解决方法!
一些思考:腾讯股价为何持续都低
Embedded Systems: Clocks
随机推荐
YOLO之父宣布退出CV界,坦言无法忽视自己工作带来的负面影响
mysql如何将表结构导出到excel
如何设计 DAO 的 PoW 评判标准 并平衡不可能三角
noip初赛
互联网用户账号信息管理规定今起施行:必须严打账号买卖灰产
Adobe是什么?
L2-041 插松枝
嵌入式系统:概述
navicat 连接 mongodb 报错[13][Unauthorized] command listDatabases requires authentication
HDU 5655 CA Loves Stick
Golang第二章:程序结构
Bytebase database schema change management tool
云平台建设解决方案
FVCOM 3D Numerical Simulation of Hydrodynamics, Water Exchange, Dispersion and Transport of Oil Spills丨FVCOM Model Watershed, Numerical Simulation Method of Marine Water Environment
UVa 1025 - A Spy in the Metro (White Book)
Optimize the query (work in progress)
目标检测技术研究现状及发展趋势
七夕快乐!
2022-08-03 oracle执行慢SQL-Q17对比
E-commerce data warehouse ODS layer-----log data loading