使用Java线程建模的客户机-服务器分配(生产者/消费者队列)

使用Java线程建模的客户机-服务器分配(生产者/消费者队列),java,multithreading,producer-consumer,Java,Multithreading,Producer Consumer,我使用Java线程和BlockingQueues(生产者和消费者队列)对客户机-服务器应用程序进行了建模,如a中所建议的 我所拥有的是服务器有一个BlockingQueue,它将把响应推送到客户端的BlockingQueue。现在的问题是如何设置客户端来调用服务器函数。我有客户端的run() while(true){ Response res=responses.take(); 开关(恢复功能){ 案例“getReservationStatus”: TreeMap reservations=(T

我使用Java线程和BlockingQueues(生产者和消费者队列)对客户机-服务器应用程序进行了建模,如a中所建议的

我所拥有的是服务器有一个
BlockingQueue
,它将把响应推送到客户端的
BlockingQueue
。现在的问题是如何设置客户端来调用服务器函数。我有客户端的
run()

while(true){
Response res=responses.take();
开关(恢复功能){
案例“getReservationStatus”:
TreeMap reservations=(TreeMap)res.data;
//System.out.println(“getReservationStatus”);
for(条目保留:reservations.entrySet()){
//System.out.println(“-”+reservation.getKey()+“\t”+(reservation.getValue()?“预订”:“可用”);
}
打破
案例“书”:
SimpleEntry数据=(SimpleEntry)res.data;
System.out.println(terminalId+”:预订座位“+data.getKey()+”+(data.getValue()?“成功”:“未成功”);
打破
}
}

我如何从我的
main()
允许用户控制向客户端发送什么命令?目前,我在
之前硬编码了我的“模拟”,而

我不确定是否理解您的问题,但我将尝试给出一个答案和一些想法:

如果希望为程序实现用户界面,必须首先定义用户可以对程序执行的操作。一种流行的方法是定义用例,并从中推断接口。让我们从这些用例中定义功能。很明显,你不再需要这一步了,因为你已经完成了应用程序的内核

你的应用程序是将请求推送到服务器,让它们得到处理并得到响应。这些请求及其参数构成了服务器可以理解的语言。同样,响应是客户端可以理解的语言,因此您可以围绕请求语言对UI进行建模。如果该语言足够简单,您可以将其表示为树,这很容易在UI中实现

您基本上有三种选择:

  • 文本输入UII:它应该是最简单的

  • 图形UII(例如swing)

  • 网络用户界面

在所有三种情况下,界面都可以建模为菜单和子菜单列表,以涵盖所有可能的请求:每个请求都是第一个菜单的条目,然后每个子菜单级别表示对所选请求的细化。你可以在这里看到与我先前暗示的一棵树的相似之处。对于图形用户界面或web用户界面(毕竟它也是图形用户界面),这几乎是微不足道的:您将在web上找到大量关于这方面的教程。对于文本输入,您可以只显示项目的编号列表(菜单),并要求用户选择一个选项

一些注意事项:

您的应用程序将模拟多个客户端与一台服务器的交互。我不知道如何在UI中实现这一点:也许可以使用一组命令来增强语言,以生成和管理客户端,并指示哪个客户端应该发送哪些请求

如果您喜欢冒险并选择了文本输入,您可以尝试建模一种真实的语言来表示您的查询,并为此实现一个解析器,这也是一个非常广泛的主题,但非常有趣。不管怎样,你可能会在以后的学习中接触到这一点

如果请求输入复杂或繁琐,您可以设计一个模板系统,用户可以在其中创建一个请求模板,命名它,然后稍后引用它,而不是再次输入相同的请求。看看我们是如何接近一种小型编程语言的

java世界中的Web应用程序通常基于相当复杂的框架和工具,为了更好地了解UI,您可能首先需要从其他选项开始


正如我在评论中提到的,对于图形用户界面,可以尝试像eclipse或netbeans这样的IDE,它可以让您轻松地以图形方式定义所有内容,并将代码挂接到特定事件(如按下按钮)

也许你误解了我的问题?我想问的是,当前当客户端
运行()
时,它只是等待响应。然后它如何发送由用户触发的响应?目前,我“模拟”在
之前发送请求,而
根据您最近的输入完全重写了我的答案,很抱歉误解。如果再次出现问题,请告诉我。我不理解为什么客户端应该发送响应,因为客户端的任务是发送请求。请澄清您的问题。您的问题是用户界面问题吗?你想让你的节目互动吗?你可以这么说。目前,我只是硬编码客户端,将请求放入服务器队列中。但我希望能够以某种方式触发客户端发送请求。如果可能的话,就目前的设置而言,它的硬件并不难,但是如果您只有一个用户,那么让多个客户端线程来发送请求是没有意义的。UI通常基于事件的概念。由于您使用的是Java,请尝试设计一个简单的图形界面,其中包含了您对用户如何首先启动查询的想法,然后尝试将两个程序连接在一起,如果您在某一点上遇到困难,请在代码中加入另一个问题。您可以轻松地使用eclipse或netbeans等IDE进行UI设计,互联网上有很多这样做的教程。
while (true) {
    Response res = responses.take();
    switch (res.function) {
    case "getReservationStatus":
        TreeMap<Integer, Boolean> reservations = (TreeMap<Integer, Boolean>) res.data;
        //System.out.println("getReservationStatus");
        for (Entry<Integer, Boolean> reservation : reservations.entrySet()) {
            //System.out.println(" - " + reservation.getKey() + " \t " + (reservation.getValue() ? "Booked" : "Available"));
        }
        break;
    case "book":
        SimpleEntry<Integer, Boolean> data = (SimpleEntry<Integer, Boolean>) res.data;
        System.out.println(terminalId + ": Booking seat " + data.getKey() + " " + (data.getValue() ? "Successful" : "Unsucessful"));
        break;
    }
}