【发布时间】:2014-03-20 12:59:25
【问题描述】:
我正在用 Java 为游戏编写一个机器人。一个线程管理 Manager 和 Worker 线程的时间并为它们发送心跳。 Manager 收集并解释来自服务器的消息,Worker 线程从 Manager 接收命令(在类中带有详细信息)并根据这些信息进行操作。
现在,我遇到了多线程死锁问题,我不确定是否有替代方案。
以下是我的管理器类中的一些方法: 当用户单击按钮时,我从 GUI 线程调用 getMessageFromUsername。从另一个线程调用以下方法。
private ArrayList<Message> MessageList = new ArrayList<>();
public synchronized Message getMessageFromUsername(String username) {
for( Message msg : MessageList ) {
if( msg.username.equalsIgnoreCase(username) ) {
Message m = new Message(msg.num, msg.username, msg.id);
return m;
}
}
return null;
}
我的管理器线程从套接字读取信息,并在一个连续循环中将信息添加到 MessageList。 (另一个,即)
private synchronized void parseMessage() {}
private void main() { while(1) { parseMessage(/*Adds message to MessageList*/); Sleep(); } }
现在,我的问题是一个非常菜鸟的问题——因为如果我想写入 MessageList,我必须使用同步来访问它。但是,由于这发生在循环中并且消息不断通过套接字进入,因此会导致死锁,因为它会一直锁定我的对象,并且这会在循环中发生。
我可以做些什么来解决我的死锁问题?
【问题讨论】:
-
最简单的方法是在循环中添加一些暂停。你可以使用
Thread.sleep() -
我在循环中使用了 100 毫秒的暂停,但由于某种原因它仍然死锁。什么是暂停的好时机?
-
错错错! @bali182 请说你在拖钓他!到底睡觉怎么会是解决僵局的正确方法?另一方面,您究竟在哪里看到了死锁?你这里有一个饥饿线程的例子。
synchronized原语不是你的解决方案,你应该使用一些优先机制。 -
@bali182 这是一个糟糕的建议。这就是为什么不应该将答案发布为 cmets 的原因,因为 cmets 不能被否决。
-
@Jason 你真的是指 deadlock 还是你真的指的是 starvation?此外,请查看
java.util.concurrent.*类,了解更精细的多线程集合方法。
标签: java multithreading sockets deadlock synchronized