Java:如何比较不同线程中的对象

Java:如何比较不同线程中的对象,java,thread-safety,Java,Thread Safety,我有一个服务器在监听来自客户端的数据。一旦客户机发送数据,它将进入一个线程。因此,每个线程都有一个数据。revFeaturePoints是服务器从客户端接收的数据 每个revFeaturePoints都有一个浮点数组,我想计算不同线程中不同revFeaturePoints之间的欧几里德距离 我不知道如何让一个线程访问其他线程中的另一个revFeaturePoints 代码如下: public class MyServer { public static void main(String[] a

我有一个服务器在监听来自客户端的数据。一旦客户机发送数据,它将进入一个线程。因此,每个线程都有一个数据。revFeaturePoints是服务器从客户端接收的数据

每个revFeaturePoints都有一个浮点数组,我想计算不同线程中不同revFeaturePoints之间的欧几里德距离

我不知道如何让一个线程访问其他线程中的另一个revFeaturePoints

代码如下:

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级别出现了无休止的内存一致性协议,这肯定会给您带来糟糕的性能。如果这确实是您想要做的,那么最好使用单线程服务器;如果我放了一个同步的