setFoo(getFoo() + 1);
  ...
  private int foo;
  public synchronized int getFoo() { return foo; } 
  public synchronized void setFoo(int f) { foo = f; }

Easy code for a race condition. Easy solution:

synchronize(o){
  o.setFoo(o.getFoo() + 1);
}
  ...
  private int foo;
  public synchronized int getFoo() { return foo; } 
  public synchronized void setFoo(int f) { foo = f; }

Now the Foo property can't be accessed through Object o, which contains it, so it's safe. But what if o is only a wrapper? Then it's only safe till every thread uses o to access the values, but if they access it with or without another wrapper, it's bad... Now still another solution:

final Object l = o.getFooLock;
synchronize(l){
  o.setFoo(o.getFoo() + 1);
}

Now it looks ok, if o is an adapter, it helps finding the real object to be locked, or it just returns itself if not. Better: synchronize(o.getBarLock) can run parallel.
But now a real problem, what if o is a wrapper for more objects, what lock to return then:

public synchronized int getFoo() { return foo1.getValue()-foo2.getValue(); } 
  public synchronized void setFoo(int f) { foo1.setValue(f/2); foo2.setValue(f/2); }
  public Object[] getFooLock() { return { foo1, foo2 }; } //Aww...
setFoo(getFoo() + 1);

Again, this code is safe till only these accessors are used, but they of course this won't always be the case.
But you can't synchronize on an array of locks (as variable number of locks) programatically in Java, or I don't know how to. I would just write an adapter for the lock too, but it's Java native, there is no method call involved. So what's the pattern to solve this in Java?
Thanks!

Found this: http://download.oracle.com/javase/6/docs/api/java/util/concurrent/locks/Lock.html
*Edit: Also this: http://download.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html
Also this: (beware, masochistic approach)

void recursivelySync(int index) {
    synchronized (arr[index]) {
        if (index != last) {
            recurseivelySync(index + 1);
        }
        else {
            callTheRealMethod();
       }
    }
}

Also please note to order the locks, to avoid deadlocking.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.