我的共享类是线程安全的吗?

时间:2014-04-17 18:45:05

标签: java multithreading thread-safety

我将在Java中的多个线程之间共享Matrix类。 Matrix类是: https://github.com/vkostyukov/la4j/blob/master/src/main/java/org/la4j/matrix/sparse/CRSMatrix.java

并且我要调用的唯一方法是获取由以下代码定义的行:

@Override
public Vector getRow(int i) {

    int rowCardinality = rowPointers[i + 1] - rowPointers[i]; 

    double rowValues[] = new double[rowCardinality];
    int rowIndices[] = new int[rowCardinality];

    System.arraycopy(values, rowPointers[i], rowValues, 0,     rowCardinality);
    System.arraycopy(columnIndices, rowPointers[i], rowIndices, 
                     0, rowCardinality);

    return new CompressedVector(columns, rowCardinality, rowValues, 
                                rowIndices);
}

所以它是只读的。您能不能帮我理解这是否会导致我的多线程程序出现问题,或者我需要使用同步还是锁定?

3 个答案:

答案 0 :(得分:2)

我看起来并不深,但看着你的代码,我可以看到这3个实例字段:

private double values[];
private int columnIndices[];
private int rowPointers[];

共享(因为它们是实例字段)。这意味着如果你提供了改变它们的方式,你可能会遇到问题。我的意思是,你在一个线程中调用getRow,而另一个线程更改其内容。当然你可能有问题。

如果你不改变它们(你只需要在创建时知道它们),那么将它们作为final并在构造函数中设置它们。并且不提供任何改变其内容的方法(方法),从而使该类不可变;因此线程安全。

否则简单使您的方法同步。

此外,您将共享一个实例,而不是该类。还有一点,关键是你的共享数据的编写者而不是读者。作家改变你的实例,而不是读者。

答案 1 :(得分:1)

你首先提出这个问题的事实意味着你对JVM没有足够的理解来编写低锁代码,所以应该避免这种情况。您还应该避免跨线程共享数据,除非它是不可变的,

答案 2 :(得分:1)

该类具有各种变更器,例如updateinsertremove,并且没有同步。该类不是线程安全的。

我假设你在问,因为你想在你自己的多线程程序中重用别人的非线程安全类。

创建对象的线程和使用它的线程之间需要有一些同步。例如,如果

  1. 线程A创建对象
  2. 线程A释放锁
  3. 线程B获取相同的锁
  4. 线程B从对象中读取
  5. 然后你应该没事。