Ich modifiziere eine Java-Server-Software. Die gesamte Anwendung ist single-threaded. Eine meiner Änderungen nimmt viel Zeit in Anspruch, daher habe ich mich entschieden, asynchron zu arbeiten, um das Einfrieren des Hauptthreads zu vermeiden.Java thread safe locking
Dies ist ein Beispiel für den ursprünglichen Code (nicht der eigentliche Code, nur ein Beispiel):
public class Packet {
private final byte[] data = new byte[1024];
public void setData(int index, byte data) {
this.data[index] = data;
}
public byte getData(int index) {
return data[index];
}
public void sendPacket(ClientConnection clientConnection) {
clientConnection.sendPacket(data);
}
}
Derzeit ist dieses mein Code (in den Kommentaren sehen):
public class Packet {
private final byte[] data = new byte[1024];
public void setData(int index, byte data) {
synchronized (this) {
this.data[index] = data;
}
}
public byte getData(int index) {
return data[index];
}
public void sendPacket(final ClientConnection clientConnection) {
//This state of data should be sent
new Thread(new Runnable() {
@Override
public void run() {
//The thread is now running
//The main-thread can move on
//The main-thread can also modify data now because we are not inside the synchronized block
//But it should not because the state of data when the method sendPacket was called should be sent
synchronized (Packet.this) {
thisTakesMuchTime(data);
clientConnection.sendPacket(data);
}
}
}).start();
}
}
Was Ich suche eigentlich etwas ist so:
public class Packet {
private final byte[] data = new byte[1024];
public void setData(int index, byte data) {
//wait for unlock
this.data[index] = data;
}
public byte getData(int index) {
return data[index];
}
public void sendPacket(final ClientConnection clientConnection) {
//lock
new Thread(new Runnable() {
@Override
public void run() {
thisTakesMuchTime(data);
clientConnection.sendPacket(data);
//unlock
}
}).start();
}
}
Die Frage: Was ist die beste Umsetzung von su ch eine Sperre in Java? Soll ich es selbst mit einer AtomicInteger
zum Beispiel machen.
Bearbeiten: Sehen Sie sich meine Antwort für meine aktuelle Implementierung.
es ist nicht ganz klar, was Sie hier fragen. Was ist die Reihenfolge der Operationen? rufe ich zuerst 'Packet.setData' und dann' Packet.sendPacket' an? Was möchten Sie tun, wenn das Paket gesendet wurde? –
Im Allgemeinen würde ich vermeiden, einen eigenen Sperrcode zu implementieren: erfinde das Rad nie neu, es sei denn, du musst es unbedingt tun. Und es gibt Dinge wie ReentrantLock ... Zeug, das gut dokumentiert ist; und von vielen anderen Leuten benutzt. Dinge "selbst" zu tun, birgt immer das Risiko, es falsch zu machen. – GhostCat
Ihre Sperre stellt sicher, dass Sie nicht in ein Paket schreiben können, während es gesendet wird, und Sie können es nicht senden, während Sie es schreiben (aus verschiedenen Threads). Das scheint nicht die beste Option zu sein. Sie sollten einen Pool für die 'clientConnection' implementieren, da so viele Pakete gleichzeitig übertragen werden können. – OldCurmudgeon