线程安全对象数组

时间:2019-02-21 06:48:49

标签: java multithreading multidimensional-array mutex java.util.concurrent

我在Java中使用二维数组。但是现在,我想将此类用于多线程。我怎样才能做到这一点?

我知道我该怎么做线程安全功能(添加同步关键字)。如果同时触发clear和getItem函数会怎样?在这种情况下,我该如何处理安全隐患?

public class ThreadSafeArray {
    int ROW_MAX_COUNT = 1024;

    int rowCount = 0;
    int counterForRow = 0;
    private Object [][] objInstances = new Object[ROW_MAX_COUNT][];

    public synchronized void addItem(Object obj) {
        if(counterForRow == ROW_MAX_COUNT) {
            objInstances[++rowCount] = new Object[ROW_MAX_COUNT];
            counterForRow = 0;
        }

        objInstances[rowCount][counterForRow++] = obj;
    }

    public synchronized  void clear() {
        objInstances = new Object[ROW_MAX_COUNT][];
        rowCount = 0;
        counterForRow = 0;
    }

    public synchronized Object getItem(int index) {
        int row = index / ROW_MAX_COUNT;
        int column = index % ROW_MAX_COUNT;

        if((row <= rowCount) && (column <= counterForRow)) {
            return objInstances[row][column];
        }
        return null;
    }
}

2 个答案:

答案 0 :(得分:4)

在您的代码中,cleargetItem是实例方法。将同步放在实例方法上意味着线程必须在该线程可以开始执行该方法中的任何代码之前,获取对该方法所调用的对象实例的锁定(“固有锁定”)。

使实例方法同步具有两种效果(来自Java指南):

  
      
  • 首先,不可能对同一对象的两次同步方法调用进行交织。当一个线程正在为对象执行同步方法时,所有其他为同一对象块调用同步方法的线程(挂起执行),直到第一个线程对该对象完成为止。
  •   
  • 第二,当同步方法退出时,它会自动与之前对同一对象的同步方法的任何后续调用建立先发生关系。这样可以保证对对象状态的更改对所有线程都是可见的。
  •   

因此,对于这两种方法,您的类已经是线程安全的。

答案 1 :(得分:2)

  

如果同时触发clear和getItem函数会发生什么?

一个人会等到另一个人结束。

  

在这种情况下,我该如何处理安全隐患?

它已经是线程安全的了。