Java同步问题——多个聊天室应用程序聊天
我正在开发一个聊天应用程序。我有一个处理聊天消息的功能。每个聊天室都由唯一的短代码标识。现在我希望当处理一个短代码的消息时,相同短代码的另一条消息应该等待,而其他短代码的消息应该继续。
请考虑遵循代码和平,它有什么问题,因为相同短代码的消息正在并行处理。我只是猜不出问题所在
private HashMap<String, Object> locks = new HashMap<String, Object>();
public void handleShortCode(String shortcode,String message,String from)
{
Object lock = null;
lock = locks.get(shortcode);
if (lock == null)
{
locks.put(shortcode, lock = new Object());
}
synchronized (lock)
{
System.out.println("Handling shortcode:" + shortcode);
// processing
System.out.println("Successfully handled shortcode:" + shortcode + " ......");
}
}
I am developing a chat application. I have a function which processes chat messages. Each chatroom is identified by unique shortcode. Now I want that when message for one shortcode is being processed, another message for same shortcode should wait, while messages for other shortcodes should carry on.
Please consider following peace of code, what is the problem with it, as messages for same shortcode are being processed in parallel. I just can't guess the problem
private HashMap<String, Object> locks = new HashMap<String, Object>();
public void handleShortCode(String shortcode,String message,String from)
{
Object lock = null;
lock = locks.get(shortcode);
if (lock == null)
{
locks.put(shortcode, lock = new Object());
}
synchronized (lock)
{
System.out.println("Handling shortcode:" + shortcode);
// processing
System.out.println("Successfully handled shortcode:" + shortcode + " ......");
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我可以看到的第一个原因是这里
这段代码在任何互斥体之外执行,因此多个线程可以同时运行它,因此每个线程(具有相同的短代码)拥有自己的锁,独立于彼此(并且只有其中一个会存储在锁 hashmap 中——问题是哪一个,因为普通 HashMap 不是为并发使用而设计的——你无法准确预测哪个“put”实际上会按哪个顺序生效,你甚至可能会遇到异常或错误的行为例如,如果当前放置导致调整大小,则此代码)。由于每个线程都获得它自己的锁,因此它不会阻止它与其他线程并发地获取它,从而获得另一个锁。
最简单(但不是很有效)的修复方法:
通过这种方式,每个短代码都可以获得一个锁。更有效的方法是使用 Guava lib 中的 ComputableConcurrentHashMap 之类的东西。
First reason I can see is here
This block of code executed outside any mutex, so several threads can run it at same time, so each of the threads (having same shortcode) got it's own lock, independent of each other (and only one of them will be stored in locks hashmap -- which one it's the question, since ordinary HashMap not designed for concurrent use -- you can't predict exactly which "put" will actualy takes effect in which order, you can even got exception or wrong behavior in this code, if current puts cause resize for example). Since each thread gets it's own lock, it does not prevent it from grabbing it in concurrent with other threads, getting another lock.
Simplest (but not very efficient) way to fix it:
This way you get exactly one lock per shortcode. The more efficient way is to use something like ComputableConcurrentHashMap from Guava lib.
同步机制很好,但也许您想看看 java.util.concurrent.locks 包中的 Lock 接口。这些使用起来比较冗长,但允许更大的灵活性,因为可以执行诸如尝试和失败之类的操作,或者尝试超时获取。
The synchronized mechanism is fine, but maybe you'd like to have a look at Lock interface in java.util.concurrent.locks package. These are more verbose to use, but allows for greater flexibility since it is possible to do things like try and fail, or try to acquire with a timeout.