Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中生成多个线程?_Java_Multithreading - Fatal编程技术网

如何在Java中生成多个线程?

如何在Java中生成多个线程?,java,multithreading,Java,Multithreading,我有一个用Java编写的聊天程序,使用一个线程、一个客户端和几个客户端,这些客户端可以联机并断开连接。 每个新用户都可以看到并与每个人交谈,每个人都可以看到他。 现在,我在那里寻找一种进行几次对话的方法。比如:第一个和第二个在私人房间,第三个和第四个在私人房间。。。。 我想用ThreadGroup这样做,但由于某些原因,我找不到一个文档可以解释我的想法是否相关。。。 不管怎样,这条路对吗? 我应该怎样做呢?如果我正确理解了您的应用程序,我不确定您是否需要线程(除非这是一项要求) 只需让每个用户注

我有一个用Java编写的聊天程序,使用一个线程、一个客户端和几个客户端,这些客户端可以联机并断开连接。 每个新用户都可以看到并与每个人交谈,每个人都可以看到他。 现在,我在那里寻找一种进行几次对话的方法。比如:第一个和第二个在私人房间,第三个和第四个在私人房间。。。。 我想用ThreadGroup这样做,但由于某些原因,我找不到一个文档可以解释我的想法是否相关。。。 不管怎样,这条路对吗?
我应该怎样做呢?

如果我正确理解了您的应用程序,我不确定您是否需要线程(除非这是一项要求)

只需让每个用户注册到一个房间-这可以是一个简单的
地图
,房间作为键,用户列表作为值。一旦您需要向某个房间发送消息,只需获取该房间中的整个用户列表(不包括发送用户),然后将消息发送给每个人

如果你想使用线程,你需要一个稍微复杂一点的模型,类似于每个房间都有一个manager线程,这可以通过一个简单的线程池和一个
ExecutorService
轻松实现,如下所示:

ExecutorService es = Executors.newFixedThreadPool(3); // or whatever
for (Runnable r : someRunnableList)
{
    es.execute(r);
}

(我强烈建议,如果您在应用程序中使用并发,请务必确保没有引入任何错误。修复并发错误不是一个愉快的考验)。

虽然不是您所问问题的答案,但如果我是您,我不会从这里开始。除非您有特定的选择线程的原因,并且您对java中的多线程编程感到满意,否则您可能会考虑使用非阻塞IO和单线程模型的一种规避方法。这个包(从Java1.4开始引入)为实现这一点提供了基础


您还可以考虑许多实现了诸如OR的解决方案的框架。使用框架的优点是,您可以在活动社区和经验证的解决方案的支持下构建单线程或安全的多线程IO应用程序(这可能是一项非常重要的任务)。

线程可能不是解决此问题的最佳解决方案。您可能会发现线程化引入了一些新的问题,这些问题只会使您的应用程序无法正常运行


正如您所描述的,可能有效的方法是用某个类的实例表示每个用户,将其称为ChatUser(目前没有更好的术语),并将允许谁与谁对话的逻辑嵌入ChatUser的方法中。例如,每个实例都有一个属性,说明用户所在的房间,当用户想说什么时,处理该属性的方法会检查ChatUser的其他实例,并只将字符串发送给那些具有匹配房间属性的实例。

我想,尽管您可以仅使用一个线程来实现,这肯定会很麻烦,因为所有的请求都是按顺序处理的,而且当涉及到网络时,它会有相当大的延迟,并且容易出现超时等情况,所以您的应用程序。很容易变得毫无反应。假设有人断开了与互联网的连接。如果您只有一个线程,则整个应用程序将一直运行,直到达到超时,并且您发现此客户端出现问题!即使有人决定安静一段时间,你也会有麻烦(这可能很容易解决,但仍然非常复杂)

因此,尽管不是中心线程,但还是非常推荐使用多线程

但是,并发专家组不鼓励使用
ThreadGroup
,因此您可能不应该使用它

我不清楚你当前应用的设计是什么。如果你能多告诉我们一点,我们也许能帮你更多

一种简单的方法是结合使用HTTP服务器和客户端。因此,每个客户机也是一个服务器,并在连接时将其回调地址(用于其服务器)传递给中央服务器。随后,客户端将通过HTTP POST将新消息推送到中央服务器,中央服务器将通过HTTP POST将这些消息推送到客户端

如果你选择这样的设计,穿线是不可避免的。。发出HTTP POST请求的线程可以是单线程(每个JVM),但接收HTTP请求的线程不能是同一个线程(这不是不可能的,但我认为不可行)

因此,最简单的方法是嵌入标识来标识组,并像这样使用(仅用于非常基本的说明!!!):

课堂聊天{
私人地图室;
{
rooms=新的ConcurrentHashMap();
}
public void connect(字符串roomKey,URI callbackAddr){
设置users=rooms.get(roomKey);
如果(用户==null){
rooms.putIfAbsent(roomKey,new ConcurrentSkipListSet());
}
users=rooms.get(roomKey);
users.add(callbackAddr);
}
public void say(字符串roomKey、字符串消息){
if(rooms.get(roomKey)==null){
抛出新的RuntimeException(“房间”+roomKey+“不存在”);
}
for(uridest:rooms.get(roomKey)){
HTTPPoster.postMessage(dest、roomKey、message);
}
}
}

你的客户也会有类似的文章。

好吧,我不得不在这个项目中使用线程,那么我认为你的想法对我来说很好……我会辩护地使用它,谢谢!
class Chat {
    private final ConcurrentMap<String,Set<URI>> rooms;
    {
        rooms = new ConcurrentHashMap<String,Set<URI>>();
    }

     public void connect(String roomKey, URI callbackAddr){
         Set<URI> users = rooms.get(roomKey);
         if(users==null){
             rooms.putIfAbsent(roomKey,new ConcurrentSkipListSet<URI>());
         }
         users = rooms.get(roomKey);
         users.add(callbackAddr);
     }

     public void say(String roomKey, String message){
         if(rooms.get(roomKey)==null){
             throw new RuntimeException("Room " + roomKey + " does not exist.");
         }

         for(URI dest : rooms.get(roomKey)){
             HTTPPoster.postMessage(dest, roomKey, message);
         }
 }

}