Я изменяю программное обеспечение сервера Java. Все приложение однопоточное. Одно из моих изменений занимает много времени, поэтому я решил сделать это асинхронно, чтобы избежать замораживания основного потока.Безопасная блокировка потоков Java
Это пример исходного кода (а не реальный код, просто пример):
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);
}
}
В настоящее время это мой код (смотреть на комментарии):
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();
}
}
Что Я действительно ищу что-то вроде этого:
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();
}
}
Вопрос: Какая наилучшая реализация su ch блокировка в Java? Должен ли я сделать это сам с AtomicInteger
, например.
Редактировать: Посмотрите на мой ответ для моей текущей реализации.
это не очень понятно, что вы спрашиваете здесь. каков порядок операций? сначала я вызываю 'Packet.setData', а затем' Packet.sendPacket'? что вы хотите сделать, когда пакет был отправлен? –
В общем, я бы не стал реализовывать свой собственный код блокировки: никогда не изобретайте колесо, если вам это не нужно. И есть такие вещи, как ReentrantLock ... материал, который хорошо документирован; и используется многими другими людьми. Выполнение вещей «самостоятельно» всегда несет риск ошибиться. – GhostCat
Ваша блокировка гарантирует, что вы не можете писать в пакет во время его отправки, и вы не можете отправить его во время записи на него (из разных потоков). Это не похоже на лучший вариант. Вы должны реализовать пул для 'clientConnection' так много пакетов может быть передано в одно и то же время. – OldCurmudgeon