java - 我应该同步 ObjectOutputStream.writeObject(Object) 吗?

标签 java multithreading concurrency io objectoutputstream

我有一个带有多个客户端的服务器。它使用一个服务器套接字和两个线程池来接收和处理来自远程客户端的请求:一个线程池 - 用于处理客户端连接,另一个线程池 - 用于处理客户端远程任务。每个客户端发送具有唯一任务 ID(在每个连接内)和一堆参数的异步任务。任务反序列化后,服务器查找相应的服务,调用其上给定的方法,将结果与任务 ID 一起包装到应答对象中,并使用 ObjectOutputStream 将其发送回客户端。 .

由于任务是并发处理的,两个或多个线程可能会同时完成一个客户端的处理任务,并尝试竞争 ObjectOutputStream

接下来会发生什么?我的意思是,他们是否以原子方式将对象写入输出流,或者我应该同步他们对 ObjectOutputStream 的访问,这样为了避免一个线程写入其对象的一半的情况 - 然后另一个线程介入......结果,一种弗兰肯斯坦对象将被发送到客户端。

import java.io.*;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.*;

public class Server {

    private final ExecutorService connExecutor = Executors.newCachedThreadPool();  
    private final ExecutorService tasksExecutor = Executors.newCachedThreadPool(); 

    public void start() {
        try (ServerSocket socket = new ServerSocket(2323);) {
            while (true) {
                try (Socket conn = socket.accept()) {
                    connExecutor.execute(() -> {
                        try (ObjectInputStream in = new ObjectInputStream(conn.getInputStream());
                             ObjectOutputStream out = new ObjectOutputStream(conn.getOutputStream())) {
                            while (true) {
                                RemoteTask task = (RemoteTask) in.readObject();
                                tasksExecutor.execute(() -> {
                                    handleTask(task, out);
                                });
                            }
                        } catch (IOException | ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                    });
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void handleTask(RemoteTask task, ObjectOutputStream out) {
        RemoteAnswer answer = new RemoteAnswer();
        // unwrap remote task 
        // lookup local service 
        // invoke task's method
        // wrap result into remote answer

        // send answer to the client 
        try {
            out.writeObject(answer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

最佳答案

这个here说得好:

Is writing an object to an ObjectOutputStream a thread-safe operation?

Absolutely not.

所以,是的,您的代码本身需要采取预防措施。

关于java - 我应该同步 ObjectOutputStream.writeObject(Object) 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58970685/

相关文章:

java - Shaker排序的条形演示一次对所有条形进行排序-Java

java - Python中有没有什么机制可以控制多线程的最大值?

c++ - 从单线程到多线程图像处理

java - 在一个线程的 JDialog 中显示一个不确定的进度条,并同时在另一个线程中运行一个任务

ios - AFNetworking:调度并发队列并在其中运行同步任务

java - 递归算法中的奇怪行为,

java - 如何在 JAVA 中对阿拉伯文本进行搜索?

c++ - 如何等待一组线程完成或 C++ 中的其他事件

java - 有多少个线程可以同时调用一个对象的非同步方法?

java - 使用 Spring Cache 抽象和 JDBC DAO 的事务