Bir Java sunucu yazılımı değiştiriyorum. Tüm uygulama tek iş parçacığıdır. Değişikliklerimden biri çok zaman alıyor, bu yüzden asıl iş parçacığını dondurmamak için bunu senkronize olmayan bir şekilde yapmaya karar verdim.Java iş parçacığı güvenli kilitleme
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);
}
}
Şu anda bu benim kodu (yorumlarına bakabilirsiniz) 'dir:
Bu
orijinal kod (değil gerçek kod, sadece bir örnektir) bir örnektirpublic 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();
}
}
neler Ben aslında şu gibi bir şey arıyorum:
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();
}
}
Soru: Su en iyi uygulama nedir ch Java'da bir kilit mi? Örneğin, bir AtomicInteger
ile kendim yapmalı mıyım?
Düzenleme: Geçerli uygulamam için yanıtıma bakın.
çok net değil. operasyonların sırası nedir? İlk önce 'Packet.setData' ve' Packet.sendPacket' olarak adlandırıyorum mı? paket gönderildiğinde ne yapmak istersin? –
Genel olarak kendi kilitleme kodunuzu uygulamaktan kaçınacağım: kesinlikle gerekmedikçe tekerleği yeniden icat etmeyiniz. Ve ReentrantLock gibi şeyler var. ve diğer birçok kişi tarafından kullanılır. "Kendini" yapmak her zaman yanlış anlama riskini taşır. – GhostCat
Kilitlemeniz, gönderilirken bir pakete yazamayacağınız ve yazarken (farklı mesaj dizilerinden) gönderemeyeceğiniz anlamına gelir. Bu en iyi seçenek gibi görünmüyor. 'ClientConnection' için bir havuz uygulamanız gerekir, böylece birçok paket aynı anda aktarılabilir. – OldCurmudgeon