If you need more flexible access patterns (such as being able to handle large sparse matrices), you might want to consider using a ConcurrentHashMap.
This data structure is thread-safe by design and allows fine-grained locking on each element (for maximum concurrency).
Here’s an example:
import java.util.concurrent.ConcurrentHashMap;
public class Matrix {
private final ConcurrentHashMap<String, Double> matrix;
private final int rows;
private final int cols;
public Matrix(int rows, int cols) {
this.matrix = new ConcurrentHashMap<>();
this.rows = rows;
this.cols = cols;
}
public double get(int row, int col) {
String key = row + "," + col;
return matrix.getOrDefault(key, 0.0);
}
public void set(int row, int col, double value) {
String key = row + "," + col;
matrix.put(key, value);
}
public int getRows() {
return rows;
}
public int getCols() {
return cols;
}
}
Explanation:
- Instead of using a 2D array, we represent the matrix as a ConcurrentHashMap with the key being a string of the form “row,column”. This makes it more flexible for sparse matrices. The ConcurrentHashMap provides thread safety out of the box and allows multiple threads to interact with different elements of the matrix without locking the entire matrix.
- This solution offers flexibility, especially if you’re working with a sparse matrix where not all elements are used.
- When to use: This is a great choice when you’re dealing with large, sparse matrices and need thread safety with frequent updates.