我正在尝试为我的大学网络做一个聊天应用程序。它实际上是两个程序:一个用于服务器,另一个用于客户端。所有客户端消息都将发送到服务器,发送方的名称和预期目标将预先添加到服务器。服务器使用此信息将消息发送给目标。
我写了一个程序,模拟了服务器端的东西,有4个类:模型、消息中心、接收者和发送者。
接收器在独立线程上生成字符串,并通过随机超时将其添加到MessageCentre中的队列中。发件人检查队列是否是空的,如果不是,它会发送消息(只需打印它)。Model类只包含启动Recector和Sender线程的main方法。
这是模拟的代码:
模范班-
package model;
public class Model {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Sender sender = new Sender();
receiver.start();
sender.start();
}
}
信息中心类-
package model;
import java.util.LinkedList;
import java.util.Queue;
public class MessageCentre {
private static Queue<String> pendingMessages = new LinkedList<>();
public static synchronized boolean centreIsEmpty() {
return pendingMessages.isEmpty();
}
public static synchronized String readNextAndRemove() {
return pendingMessages.remove();
}
public static synchronized boolean addToQueue(String message) {
return pendingMessages.add(message);
}
}
接收级-
package model;
import java.util.Random;
public class Receiver extends Thread {
private int instance;
public Receiver() {
instance = 0; //gets incremented after each message
}
@Override
public void run() {
while (true) {
boolean added = MessageCentre.addToQueue(getMessage());
if (!added) {
System.out.println("Message " + instance + " failed to send");
}
try {
//don't send for another 0 to 10 seconds
Thread.sleep(new Random().nextInt(10_000));
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
private String getMessage() {
int copyInstance = instance;
instance++;
return "Message " + copyInstance;
}
}
发件人类别-
package model;
public class Sender extends Thread {
@Override
public void run() {
while(true) {
if(!MessageCentre.centreIsEmpty()) {
System.out.println(MessageCentre.readNextAndRemove());
}
}
}
}
问题:如果将接收器类的getMessage()
方法替换为从套接字输入流接受消息的方法,是否有可能丢失一些消息?
至关重要的是,所有接收到的消息都要写入队列,这样就不会丢失任何消息。这个模拟似乎运行良好,但我无法测试通过套接字接收大量消息的场景。
我担心可能发生的情况如下:
接收器获取消息并尝试将其写入队列。发件人持有队列以读取和删除其中的项,从而阻止接收者写入最新的消息。接收器最终有机会将当前消息写入队列,但同时进入套接字输入流的新消息将永远丢失。
这种情况可能吗?如果是的话,是否可以通过将接收者的优先级设置为高于发送者来防止?
一条新消息同时进入套接字输入流,将永远丢失
总是有可能的,但是不太可能有大量被丢弃的请求,除非您的负载很重或者有不必要的大的关键部分。请求被丢弃也是由于您无法控制的因素造成的,因此您的系统无论如何都需要在面对这些因素时保持健壮。
使用java中的队列实现。util。并发
而不是在链接列表上手动同步
,代码的队列部分应该可以。
问题内容: public class Deadlock { static class Friend { private final String name; public Friend(String name) { this.name = name; } public String getName() { return this.name; } public synchronized void b
下面是我的代码: 我将再次指出,如果我使用队列而不是优先级队列,那么代码可以工作。如何访问优先级队列的前部?
问题内容: 我在Java中的线程上有些挣扎,我有三个线程- 线程1,线程2和线程3。那些启动时正在执行某些任务,我想通过thread1停止这两个线程。我将thread1放在,然后停止两个线程,但是两个线程的进程仍在运行。你有什么想法吗? 问题答案: 您如何试图阻止他们??警告此方法已弃用。 而是考虑对线程1使用某种标志来与线程2和3通信,它们应该停止。实际上,您可能会使用interrupts。 下
问题内容: 我相信我的问题很简单。我正在做在裸机上安装Kubernetes集群的先决条件。 假设我有: 主 -主机名泊坞DB容器,其被固定第一节点上 从属 -主机名泊坞DB容器,其被固定第二个节点上 我是否可以从群集中的任何容器(应用程序等)与 master 通信,而不管它是否在同一节点上运行? 这是默认行为吗?还是应该做其他的事情? 我假设我需要在YAML或JSON文件中设置参数,以便Kuber
我写了一个启动两个线程的代码片段;一个线程打印所有奇数,而另一个线程打印所有偶数。我使用了内在锁和线程通信命令的组合来实现两个线程的正确交叉。这是我的代码, 以下是我的问题: > 奇数线程在printOdd()函数中执行,而偶数线程在print偶数()函数中执行。我对两个线程都使用一个内在锁;我不明白两个线程怎么能同时存在于各自的同步块中,因为使用了相同的锁。 我从代码中删除了线程通信语句(通知,
我必须得到如下输出: 这是我的密码。没有错误。它以PlusThread开始并打印第一行。然后它将释放锁。之后,MultiplyThread开始运行。它将打印所有行,而不是通知PlusThread。 这是我的输出: