gpt4 book ai didi

Java线程安全锁定

转载 作者:行者123 更新时间:2023-11-30 08:02:51 26 4
gpt4 key购买 nike

我正在修改 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();
}
}

问题:Java 中这种锁的最佳实现是什么?例如,我是否应该使用 AtomicInteger 自己完成。

编辑:查看我当前实现的答案。

最佳答案

您可以复制数据并发送副本,以避免并发。

public class Packet {
private final byte[] data = new byte[1024];

public void setData(final int index, final byte data) {
this.data[index] = data;
}

public byte getData(final int index) {
return data[index];
}

public void sendPacket(final ClientConnection clientConnection) {
byte[] dataToSend = new byte[1024];
System.arraycopy(data, 0, dataToSend, 0, 1024);
new Thread(new Runnable() {
@Override public void run() {
clientConnection.sendPacket(dataToSend);
}
}).start();
}
}

使用 CopyOnWriteArrayList 类似于下面的代码,它也避免了并发但效率不高(假设您调用 setData 的次数比 sendPacket ):

public class Packet {
private byte[] data = new byte[1024];

public void setData(final int index, final byte data) {
byte[] newData = new byte[1024];
System.arraycopy(data, 0, newData, 0, 1024);
newData[index] = data;
this.data = newData;
}

public byte getData(final int index) {
return data[index];
}

public void sendPacket(final ClientConnection clientConnection) {
new Thread(new Runnable() {
@Override public void run() {
clientConnection.sendPacket(data);
}
}).start();
}
}

关于Java线程安全锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36573565/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com