Java:如何比较不同线程中的对象
我有一个服务器在监听来自客户端的数据。一旦客户机发送数据,它将进入一个线程。因此,每个线程都有一个数据。revFeaturePoints是服务器从客户端接收的数据 每个revFeaturePoints都有一个浮点数组,我想计算不同线程中不同revFeaturePoints之间的欧几里德距离 我不知道如何让一个线程访问其他线程中的另一个revFeaturePoints 代码如下:Java:如何比较不同线程中的对象,java,thread-safety,Java,Thread Safety,我有一个服务器在监听来自客户端的数据。一旦客户机发送数据,它将进入一个线程。因此,每个线程都有一个数据。revFeaturePoints是服务器从客户端接收的数据 每个revFeaturePoints都有一个浮点数组,我想计算不同线程中不同revFeaturePoints之间的欧几里德距离 我不知道如何让一个线程访问其他线程中的另一个revFeaturePoints 代码如下: public class MyServer { public static void main(String[] a
public class MyServer {
public static void main(String[] args) throws IOException{
ServerSocket serverSocket = null;
//bind a serverSocket to the port and listen
try{
serverSocket = new ServerSocket(8888);
System.out.println("Listening: 8888");
}catch(IOException e){
e.printStackTrace();
}
while(true)
new MyServerThread(serverSocket.accept()).start();
}
}
public class MyServerThread extends Thread{
//Create a socket for each client
private Socket socket = null;
private ObjectInputStream dataInputStream = null;
private ObjectOutputStream dataOutputStream = null;
private ArrayList<FeaturePointList> revFeaturePoints = null;
//constructor
public MyServerThread(Socket socket){
super("MyServerThread");
this.socket = socket;
}
@SuppressWarnings("unchecked")
public void run(){
try{
dataOutputStream = new ObjectOutputStream(socket.getOutputStream());
dataInputStream = new ObjectInputStream(socket.getInputStream());
System.out.println("ip: "+ socket.getInetAddress());
revFeaturePoints = (ArrayList<FeaturePointList>) dataInputStream.readObject();
}catch(IOException e){
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if(socket!=null){
try{
socket.close();
}catch(IOException e){
e.printStackTrace();
}
}
if(dataInputStream!=null){
try{
dataInputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
if(dataOutputStream!=null){
try{
dataOutputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
公共类MyServer{
公共静态void main(字符串[]args)引发IOException{
ServerSocket ServerSocket=null;
//将serverSocket绑定到端口并侦听
试一试{
serverSocket=新的serverSocket(8888);
System.out.println(“侦听:8888”);
}捕获(IOE异常){
e、 printStackTrace();
}
while(true)
新建MyServerThread(serverSocket.accept()).start();
}
}
公共类MyServerThread扩展线程{
//为每个客户端创建一个套接字
私有套接字=空;
私有ObjectInputStream dataInputStream=null;
私有ObjectOutputStream dataOutputStream=null;
private ArrayList revFeaturePoints=null;
//建造师
公共MyServerThread(套接字){
超级(“myserver线程”);
this.socket=socket;
}
@抑制警告(“未选中”)
公开募捐{
试试{
dataOutputStream=新的ObjectOutputStream(socket.getOutputStream());
dataInputStream=新的ObjectInputStream(socket.getInputStream());
System.out.println(“ip:+socket.getInetAddress());
revFeaturePoints=(ArrayList)dataInputStream.readObject();
}捕获(IOE异常){
e、 printStackTrace();
}catch(classnotfounde异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
最后{
if(套接字!=null){
试一试{
socket.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
如果(dataInputStream!=null){
试一试{
dataInputStream.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
如果(dataOutputStream!=null){
试一试{
dataOutputStream.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
}
}如果您的
MyServerThread
类将数据存储到一个字段中,您可以从MyServerThread
的多个实例访问该字段。一个简单的方法是在MyServerThread
中放入一个同步方法,返回数据
另一种方法是使用BlockingQueue并将数据结果放入队列中,并将结果作为生产者-消费者模式。请参阅以了解执行此操作的方法。通过使用共享结构和正确的同步,可以在线程之间共享数据。例如,您可以在
MyServerThread
中有一个ConcurrentHashMap
,其中每个线程放置其数据并在其他线程中搜索数据
也就是说,您应该评估您的体系结构。如果N个线程必须检查其他N-1个线程对数据做了什么,那么您正在准备一个性能灾难的配方。也许,您想做的是在您的体系结构中创建一些分层,其中许多服务器线程正在收集请求并将它们放置在并发共享结构(例如队列)中。然后,另一组工作人员在一个协作系统中比较和处理数据并生成结果。看一下。[确实是一个评论,但不适合;)] maasg的回答在一般意义上是非常正确的,但我相信您现在看到的是设计困难,而不是Java线程实现本身 服务器(按原样)在每个连接请求上触发一个一次性线程,该线程只是从客户端读取一个对象,然后关闭连接。传递的对象被放入(服务器线程)实例范围的对象中(在退出run()后,该对象会被适当地垃圾收集) 我们完全不清楚——因此这是一个设计问题的印象——如何确定要比较哪两个线程,或者对于这一点,如何保证(总是)有两个并发线程开始
从逻辑上讲,服务器线程和域中某些有意义的内容之间显然存在特定于域的关联。这种关系需要体现在代码中,但首先我们需要了解这种区别和关系是什么。对象不是“在不同的线程中”。对象是其他不同对象的成员,通常通过“get”方法引用。完全忘记线程问题,它是无关的。您只想将对象a的成员与对象B的成员进行比较。这只是照常操作。将数据存储到字段中是什么意思?这是我收到的数据。revFeaturePoints=(ArrayList)dataInputStream.readObject()@wzb5210:只需将
revFeaturePoints
设为一个字段。你能给我举个例子吗?我不知道。@wzb5210在您的MyServer
类中有一个字段(又名对象属性)。Chris在这里(大概)假设您只需要一个变量来保存写入的'last'(?)revFeaturePoints
。如果你走这条路,一定要和volatile
关键字交朋友。您还需要序列化对该字段的访问(通过锁或synchronized
关键字)。当然,由于cpu级别出现了无休止的内存一致性协议,这肯定会给您带来糟糕的性能。如果这确实是您想要做的,那么最好使用单线程服务器;如果我放了一个同步的