当前位置: 首页 > 知识库问答 >
问题:

Java线程安全锁定

祁绪
2023-03-14

我正在修改一个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亲自完成。

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

共有1个答案

都建树
2023-03-14

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

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版相关面试题,主要包含被问及双重检查加锁单例 线程安全-Java版时的应答技巧和注意事项,需要的朋友参考一下 双重检验加锁模式(double checked locking pattern),是一种使用同步块加锁的方法。程序员称其为双重检查锁,因为会有两次检查 ,一次是在同步块外,一次是在同步块内。为什么在同步块内还要再检验一次?因为可能会有多个线

  • 我找到了关于线程安全的代码,但它没有来自给出示例的人的任何解释。我想知道为什么如果我不在“count”之前设置“synchronized”变量,那么count值将是非原子的(总是=200是期望的结果)。谢谢

  • 问题内容: 我需要一个线程安全映射,我有类似这样的内容:(我对Java很陌生) 问题答案:

  • 问题内容: 我有一个函数,该函数使用和来搜索字符串列表中的模式。 此函数用于多个线程。每个线程将在创建线程时传递给的唯一模式。线程和模式的数量是动态的,这意味着我可以在配置期间添加更多s和线程。 如果使用正则表达式,是否需要在此函数上放一个?Java线程中的正则表达式安全吗? 问题答案: 是的 ,来自Pattern类的Java API文档 此类(模式)的实例是不可变的,可以安全地由多个并发线程使用

  • 问题内容: 经过一番认真的搜索后,我发现RandomAccessFile- class不是线程安全的。现在,我可以使用一个信号量来锁定所有读取和写入,但是我认为这样做的效果不是很好。从理论上讲,一次可以进行多次读取和一次写入。如何用Java做到这一点?有可能吗? 谢谢! 问题答案: 文件的部分锁定是一项复杂的业务,许多操作系统都避免这样做。但是,如果您坚持要这样做,一种方法是设计自己的锁定机制对象

  • 问题内容: 我有两个线程。第一个在循环中使用MulticastSocket发送数据报;第二个线程在循环中使用相同的MulticastSocket实例接收数据报。 它似乎工作正常,但我仍然对此表示怀疑。 这两个线程可以使用同一MulticastSocket实例吗?在发送/接收方法调用方面,MulticastSocket线程安全吗? 问题答案: 发送和接收DatagramSocket方法都在发送/接收