我有一个简单的服务器任务,需要监听数据包并经常保存它们。这是我正在使用的代码:
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
}
}
现在,由于Timer使用另一个Thread
,我可能应该同步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
}
}
答案 0 :(得分:3)
我是否必须[同步对
lastPacket
]的访问权限?
不,您不必这样做:因为您有兴趣在计时器触发时大致写出最后一个数据包,并且因为接收器线程不会改变现有数据包,所以不需要同步。
使lastPacket
volatile变得足以实现逻辑:
private volatile Packet lastPacket;
注意:上面假设fromClient.readObject();
返回一个全新的对象,该对象独立于lastPacket
对象。
答案 1 :(得分:0)
在每个请求到来时使用池中的新线程或线程,