使用Java线程为单线程TCP套接字服务器的客户端添加并发性

使用Java线程为单线程TCP套接字服务器的客户端添加并发性,java,multithreading,tcp,Java,Multithreading,Tcp,我正在使用第三方FooClientImplJava类,它实现FooClient接口: interface FooClient { public FooOutput processFoo(FooInput inputData); } 它通过在localhost上的特定端口号上的TCP套接字与第三方非Javafooserver进程通信来处理传递给它的数据。每个inputData实例都可以独立处理(即,它的并行性令人尴尬)fooserver相当慢,但只在单个核心上运行,因此我希望能够在单独的

我正在使用第三方
FooClientImpl
Java类,它实现
FooClient
接口:

interface FooClient {
    public FooOutput processFoo(FooInput inputData);
}
它通过在
localhost
上的特定端口号上的TCP套接字与第三方非Java
fooserver
进程通信来处理传递给它的数据。每个
inputData
实例都可以独立处理(即,它的并行性令人尴尬)
fooserver
相当慢,但只在单个核心上运行,因此我希望能够在单独的端口上手动启动多个实例,并有多个
FooClientImpl
实例来访问它——每个服务器实例一个。到目前为止,这很容易

然而,我还想创建一个
ConcurrentFooClientImpl
类,它也实现了
FooClient
接口,但是在后台,跟踪
FooClientImpl
实例或子类实例(可能是8个)的池,并使用
.processFoo()之后的第一个未使用实例处理传入数据
方法被调用(如有必要,等待一个方法可用)。这样,其他代码可以实例化ConcurrentFooClientImpl,调用代码看起来也一样,只是速度更快

我对线程非常陌生,我已经浏览了,但是这个用例似乎与这里的示例有所不同

我想我需要创建一个
Thread
子类
fooclientmplthread
,它封装了一个
fooclientmpl
实例。我认为我还应该使用它来管理一个固定大小的客户机池,它应该有一个可以生成
fooclientmplthread
实例的。然后在
ConcurrentFooClientImpl.processFoo()
中,我可以将
inputData
以某种方式包装到的实现中,以将它们提交到池中。但是这些实例需要获得一个特定的
FooClient
实例,这样它们就可以依次调用
fooclientmplthread.processFoo()
,并实际与相应端口上运行的
fooserver
对话。我想他们可以调用并将结果强制转换为
fooclientmplthread
。但直觉上我觉得这有点不对劲(虽然我不知道是否相信我的直觉),我也不确定这是否有效或是否合理

我是否在正确的轨道上找到了可能的解决方案,还是应该采取更明智的方法


更新:我最终实现了一个类似于上述解决方案的解决方案。令人惊讶的是,它基本上按照预期工作,当然我意识到在维护外向API的同时,我没有考虑到后台处理需要什么。据我所知,这在我上面概述的调用方触发的API中是不可能的。它需要被生产者-消费者模式或其他什么东西所取代,我最终做了这件事,尽管方式不同。

你做得太过分了。您所需要的只是对服务器的TCP部分进行多线程处理,即为每个接受的套接字启动一个新线程。然后,要么这些线程都可以共享同一个FooImpl对象,要么每个线程都有自己的一个对象,只要考虑到FooImpl的实现方式,哪个线程都有意义。你不需要一个新的线程类;你什么都不需要。注意:如果不知道Java对象是单线程的,那么说任何Java对象只在一个内核中运行是不正确的。

对不起,我应该更清楚一些(我现在编辑了这个问题)。
fooserver
进程不是用Java编写的——它实际上是一个基于Prolog的服务器(尽管这并不特别相关),我无法控制它。据我所知,它使用单个内核对单个TCP侦听器端口进行繁重的处理。我确实考虑编写java socket服务器包装器(或其他语言)来侦听单个端口并将其发送到可用的<代码> FooServer 端口,但我不认为这会更容易。“奇怪的特性,您确定这一点吗?”您是否尝试过同时将两个客户端连接到它?用任何语言编写一次只能处理一个客户机的TCP服务器都是非常不寻常的。很好的一点是,我实际上并没有尝试过简单而明显的事情。但是,服务器进程似乎没有使用工作线程。使用第三方下游库,当我在双核笔记本电脑上创建3个客户端实例时,速度降低了13%。我知道我不应该期望50%,但这似乎表明我没有得到有用的并行化。
fooserver
进程的CPU使用率也没有达到100%。(我可以想到一种简单的TCP服务器可能不支持并发性的语言—Python及其应用程序,我现在可以确认,当有多个客户端线程且有多个服务器实例侦听多个端口(每个客户端线程一个)时,我确实获得了很大(~45%)的加速,所以看起来这是一个异常编写的服务器的实例。因此,我在问题中描述的这种卷积将是有用的(除非我最终使用一些第三方代码以不同的方式实现它们)@奇怪的功能由于你没有得到3倍的减速,显然服务器是多线程的,尽管可能不是很好。你必须获得一些并发性,否则三个客户端的时间都是三倍。所以我仍然认为你找错了方向。