I have two arrays, and I need to synchronize access to them across threads. I am going to put them in a synchronized block. The problem is, I can pass only one of them to 'synchronized' st one go.
How do I ensure that the access to both the arrays is synchronized? Do I put them in a class and create an object of it? Or I access the other array only in the synchronized block, and this takes care of synchronized access to it?
Thanks,
Prior to Java 5, I'd have written things like this:
// pre Java 5 code:
Object lock = new Object();
// ...
synchronized(lock) {
// do something that requires synchronized access
}
But since Java 5, I'd use classes from java.util.concurrent.locks
(personally, I don't find this more complicated or error-prone):
// Java 5 Code Using Locks
Lock lock = // ...
lock.lock();
try {
// do something that requires synchronized access
}
finally {
lock.unlock();
}
If you need read-write locking, here is example implemented using read-write locks from Java 5:
private ReadWriteLock rwl = new ReentrantReadWriteLock();
private Lock rLock = rwl.readLock();
private Lock wLock = rwl.writeLock();
private List<String> data = new ArrayList<String>();
public String getData(int index) {
rLock.lock();
try {
return data.get(index);
} finally {
rLock.unlock();
}
}
public void addData(int index, String element) {
wLock.lock();
try {
data.add(index, element);
} finally {
wLock.unlock();
}
}
Of course, adapt it to suit your needs.
Whatever you do don't do this:
synchronized (array1) {
synchronized (array2) {
// do stuff
}
}
This is likely to lead to deadlock unless you are very careful. If you do this approach, you must ensure you have an unchanging partial order on the objects - Google "Dining Philosophers" for discussion of the pitfalls.
Basically what you have to do is create one lock object that you will use if you want to access either array and then use that for all array access. It's coarse-grained but safe. You could do it this way:
public static class TwoArrays {
private int[] array1 = ...
private int[] array2 = ...
private final Object LOCK = new Object();
public void doUpdate() {
synchronized (LOCK) {
...
}
}
}
If you need a finer-grained method you want to use the Java 5+ concurrent utilities such as ReadWriteLock
but this will be more complicated to implement and error-prone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With