Java 多线程环境中的数组。读写两种语言

Java 多线程环境中的数组。读写两种语言,java,arrays,multithreading,thread-safety,Java,Arrays,Multithreading,Thread Safety,我有一个长度为100的数组。我需要在多线程环境中使用它。总共有10个线程访问阵列。可能有两个线程t1和t2希望一次写入同一个索引 Object[] data = new Object[100]; 实现这一点的最佳方法是什么 解决方案1: 只有一个线程可以写入数组。即使t1和t2线程想要写入不同的索引,也必须等待。甚至我们可以使用arrayList,也可以使用Collections.synchronizedList(..) 解决方案2: 两个不同的线程可以在两个不同的索引上同时写入

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

Object[] data = new Object[100];
实现这一点的最佳方法是什么

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

解决方案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
      } 
    }
  }

是否有更好的方法来实现此要求?

如果有许多线程试图写入大量单元,那么第二种解决方案会更好,而第一种方法可能会在第二种解决方案中造成瓶颈


在给定的10个线程和100个单元的情况下,在现代计算机中没有太大的区别

如果有很多线程试图写入许多单元,那么第二种解决方案会更好,而第一种方法可能会在第二种解决方案中造成瓶颈


在给定的10个线程和100个单元格的情况下,现代计算机中没有太大的差别

在java中,根据您打算如何使用数组,可以将值放在AbstractQueue ArrayList中。这是一个有用的方法

或任何类似的队列,例如

  • 阵列锁定队列
  • 延迟队列
  • LinkedBlockingDeque
  • 同步队列

在java中,根据您打算如何使用数组,可以将值放在AbstractQueue ArrayList中。这是一个有用的方法

或任何类似的队列,例如

  • 阵列锁定队列
  • 延迟队列
  • LinkedBlockingDeque
  • 同步队列

我会选择解决方案1:

我认为它非常适合你的需要

我认为性能问题可以忽略不计

synchronize 
你的访问权限完成了任务。为什么要让它变得比现在更难呢

提示:I不会使用数组。我最好使用集合。有一个收藏
满足您的所有需求。

我会选择解决方案1:

我认为它非常适合你的需要

我认为性能问题可以忽略不计

synchronize 
你的访问权限完成了任务。为什么要让它变得比现在更难呢

提示:I不会使用数组。我最好使用集合。有一个收藏
适合您需要的每个人。

这取决于线程是只写入值还是同时读取值(例如,将值增加一)。如果它们读取,则在覆盖所有值(读和写)的区域上同步。如果从不同的单元格读取,则为第一个变量。如果仅来自同一销售,则为第二个变体。如果没有读取值,则根本不需要同步。

这取决于线程是只写入值还是同时读取值(例如,将值增加一)。如果它们读取,则在覆盖所有值(读和写)的区域上同步。如果从不同的单元格读取,则为第一个变量。如果仅来自同一销售,则为第二个变体。如果没有读取任何值,那么您根本不需要同步。

首先让我们讨论一下,如果我们在多个线程之间共享任何数据,无论是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];
现在,如果没有synchronized关键字,您的get方法就可以正常工作了

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/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];
现在,如果没有synchronized关键字,您的get方法就可以正常工作了

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中的
Vector
CopyOnWriteArrayList
你这样做是为了练习还是重新发明轮子。此外,这个问题更适合codereview.stackexchange。com@NarendraPathai exercise@NarendraPathai做