gpt4 book ai didi

java - 数组 在多线程环境中。读和写都

转载 作者:太空宇宙 更新时间:2023-11-04 07:29:21 24 4
gpt4 key购买 nike

我有一个长度为100的数组。我需要在多线程环境中使用它。总共有10个线程访问数组。两个线程 t1t2 可能希望同时写入同一个索引。

Object[] data = new Object[100];

实现此目的的最佳方法是什么。

解决方案1:只有一个线程可以写入数组。即使 t1 和 t2 线程想要写入不同的索引,也必须等待。甚至我们可以使用 arrayList 并可以使用 Collections.synchronizedList(....)。

  public class ThreadSafeArray(){
private Object[] data = new Object[100];

public synchronized Object getValueAtIndex(int index){
return data[index]; // Removing index range check for simple explanation
}

public synchronized void setValueAtIndex(int index , Object value){
data[index] = value; // Removing index range check for simple explanation

}
}

解决方案 2:两个不同的线程可以同时写入两个不同的索引。

        public class ThreadSafeArray(){
private Object[] data = new Object[100];
private Object[] lock = new Object[100];

public Object getValueAtIndex(int index){
synchronized(lock[index])
{
return data[index]; // Removing index range check for simple explanation
}
}

public void setValueAtIndex(int index , Object value){
synchronized(lock[index])
{
data[index] = value; // Removing index range check for simple explanation
}
}
}

有没有更好的方法来实现这个需求?

最佳答案

首先让我们讨论一下如果我们在多个线程之间共享任何数据(无论是 Java/C#)会遇到什么问题。我们需要解决三个问题。

1. **Atomicity** of read/write operation on that datastructure
2. **Visibility** changes by one thread are visible to other thread.
3. **Reordering** - compiler n processor are free to reorder these instruction
as long as it maintains program order for single thread execution.

现在对于你的问题我看到的是。您有一个固定大小的数组,并且在多个线程之间共享,并且您只是设置和获取值。

首先,引用分配是原子的因此,您的以下方法是原子的。我不会说它是线程安全的。因为它仍然缺乏可见性保证。

public void setValueAtIndex(int index , Object value){
data[index] = value; // Removing index range check for simple explanation
}

现在,为了保证可见性,我们可以改变我们的方法(以防您读取的数量超过写入的数量)

首先让您的数组声明为 volatile

volatile Object [] data = new Object[100];

现在你的 get 方法无需使用synchronized关键字就可以正常工作

public Object getValueAtIndex(int index){
return data[index]; // Removing index range check for simple explanation
}

上面的方法是线程安全的现在对于 set 方法,您可能需要复制数组更改值,然后再次重新分配数据,即

public void setValueAtIndex(int index , Object value){
Object tempdata = copy(data); // make a copy of that array
//change in the copied array
tempdata[index] = value;
// reassign the array back to original array
data = tempData;
}

通过上述方法,您将以写入数组的成本提高读取数组的性能。 如果你有固定长度的数组,则不需要同步,否则你需要锁定来进行突变操作

关于java - 数组 在多线程环境中。读和写都,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17991841/

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