Java 我需要同步这个吗?如果是,怎么做?

Java 我需要同步这个吗?如果是,怎么做?,java,multithreading,synchronization,Java,Multithreading,Synchronization,我有一个简单的服务器任务,需要监听数据包并经常保存它们。这是我正在使用的代码: class ServerTask implements Runnable { private final Socket client; private final Timer timer; private Packet lastPacket; public ServerTask(Socket client) { this.client = client;

我有一个简单的服务器任务,需要监听数据包并经常保存它们。这是我正在使用的代码:

class ServerTask implements Runnable {

    private final Socket client;
    private final Timer timer;
    private Packet lastPacket;

    public ServerTask(Socket client) {
        this.client = client;
        this.timer = new Timer();

        timer.scheduleAtFixedRate(
            new TimerTask() {
                @Override
                public void run() {
                    saveLastPacketToLog();
                }
            }, 60*1000, 60*1000);
    }

    public void run() {
        try (ObjectInputStream fromClient = new ObjectImputStream(client.getOutputStream())) {
            while (running) {
                lastPacket = (Packet) fromClient.readObject();
            }
        } catch (Exception e) {
            ... 
        }
    }

    public void saveLastPacketToLog() {
        // ... open file, serialize lastPacket and write it there
    }
}
现在,由于计时器使用了另一个
线程
,也许我应该将访问同步到
lastPacket
。我必须这样做吗?如果是,如何做到这一点?我曾想过这样做,但我不确定,因为我没有太多的多线程经验:

class ServerTask implements Runnable {

    private final Socket client;
    private final Timer timer;
    private Packet lastPacket;

    public ServerTask(Socket client) {
        this.client = client;
        this.timer = new Timer();

        timer.scheduleAtFixedRate(
            new TimerTask() {
                @Override
                public void run() {
                    saveLastPacketToLog();
                }
            }, 60*1000, 60*1000);
    }

    public void run() {
        try (ObjectInputStream fromClient = new ObjectImputStream(client.getOutputStream())) {
            while (running) {
                synchronized(this){
                    lastPacket = (Packet) fromClient.readObject();
                }

            }
        } catch (Exception e) {
            ... 
        }
    }

    public synchronized void saveLastPacketToLog() {
        // ... open file, serialize lastPacket and write it there
    }
}
我必须[同步访问
lastPacket
]吗

不,您不必这样做:因为您感兴趣的是大约在计时器启动时写出最后一个数据包,并且因为接收方线程不改变现有数据包,所以不需要同步

使
lastPacket
易失性应足以实现逻辑:

private volatile Packet lastPacket;

注意:以上假设
fromClient.readObject()
返回一个全新的对象,它独立于
lastPacket
对象。

在每个请求出现时使用一个新线程或池中的线程,

如果可见性是您唯一关心的事情,我会使用volatile,似乎就是这样。