我必须设计一个简单的服务器,它接收来自多个节点的消息并将它们存储在消息库中。
服务器的代码是:
public class CommunicationServer implements Runnable {
private List<String> messages;
private MessageRepository messageRepository;
private boolean serverBusy;
public CommunicationServer() {
messages = new ArrayList<String>();
messageRepository = new MessageRepository();
serverBusy = false;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
if (messages.size() > 10) {
serverBusy = true;
addMessageToRepository();
notifyAll();
}
else {
serverBusy = false;
wait();
}
}
}
}
catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
public synchronized void receiveMessage(String message) {
if (messages.size() < 10) {
messages.add(message);
}
}
private void addMessageToRepository() {
if (messages.size() != 0) {
messageRepository.addMessage(messages.remove(0));
}
}
public void showMessageRepository() {
messageRepository.showStoredMessages();
}
public synchronized boolean isServerBusy() {
return serverBusy;
}
}
节点的代码是:
public class Node implements Runnable {
private static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ0123456789";
private static final int MESSAGE_LENGHT = 5;
private Random random = new Random();
private CommunicationServer communicationServer;
public Node(CommunicationServer communicationServer) {
this.communicationServer = communicationServer;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
while (communicationServer.isServerBusy()) {
wait();
}
communicationServer.receiveMessage(generateRandomString());
}
}
catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
private String generateRandomString() {
StringBuffer randomMessage = new StringBuffer();
for (int i = 0; i < MESSAGE_LENGHT; i++) {
randomMessage.append(CHARACTERS.charAt(random.nextInt(51)));
}
return randomMessage.toString();
}
}
在main中我只为服务器创建一个线程,为节点创建5个线程,让它们运行一段时间。服务器休眠直到收到10条消息,之后必须唤醒它才能处理消息。问题是我无法弄清楚在哪里调用notifyAll()以唤醒负责服务器的线程。
答案 0 :(得分:1)
让CommunicationServer implements Runnable
真的没有意义,并暴露了你的基本误解:你用线程 actors >。线程不是演员;一个线程是演员代码被执行的地方。
因此,当您在CommunicationServer
中说wait()
时,您不会让服务器等待消息;您将该特定的线程等待服务器对象作为其监视器。同样,那么你说notifyAll()
,你不是&#34;通知所有服务器&#34 ;;您正在通知在该特定监视器上等待的所有线程。它应该是客户端中的一些代码,它通知当前正在服务器监视器上等待的线程,以及服务器中的一些代码,通知在客户端监视器上等待的那些代码。
作为一般经验法则,当您发现自己在同一个同步块中同时使用wait()
和notify()
时,您可以非常确定您的逻辑存在问题。< / p>