I'm reading chapter 2 of " The Art of Multiprocessor Programming " and I'm confused about Filter algorithm which looks like so:
class Filter implements Lock {
int[] level;
int[] victim;
public Filter(int n) {
level = new int[n];
victim = new int[n]; // use 1..n-1
for (int i = 0; i < n; i++) {
level[i] = 0;
}
}
public void lock() {
int me = ThreadID.get();
for (int i = 1; i < n; i++) { //attempt level 1
level[me] = i;
victim[i] = me;
// spin while conflicts exist
while (( ∃ k != me) (level[k] >= i && victim[i] == me)) {};
}
}
public void unlock() {
int me = ThreadID.get();
level[me] = 0;
}
}
What looks strange to me, is that level
and victim
arrays are not made volatile
. Prior to this algorithm, the author presented less general "Peterson algorithm", where variables are set like so:
private volatile boolean[] flag = new boolean[2];
private volatile int victim;
So my question is why in a more general algorithm we do not specify level
and victim
as volatile
?
Firstly volatile
is like final
or static
in that it only applies to the field, not the object referenced. eg
volatile int[] level;
means writes to level
not level[0]
are volatile.
In fact there is no way to do this in natural Java which is why AtomicIntegerArray
uses Unsafe
to perform volatile and thread safe operations.
In short, the only real solution is to use AtomicIntegerArray
(or Unsafe
directly).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.