0

I have a class A and B.

public class A() { 
    private static List<int> list = new ArrayList<int>(); 
    public static List<int> getList() {
        return list;
    }
}

public class B() { 
    public void foo() {
        synchronized(A.getList()) {
            // DO Stuff
        }
    }
}

In class B where I synchronize. Does this synchronize on A's list, or on B's reference to A's list. I think it is the latter but could use some help.

If so then how do I accomplish a similar thing to this that will actually work?

Thanks!

w.donahue
  • 10,790
  • 13
  • 56
  • 78
  • Perhaps this code is just for the question at hand, but it is a bad implementation for synchronization. I'm assuming that you are modifying the stuff in the list in the synchronized block. The reason it is bad is that some other piece of code could call A.getList() directly, and bypass the synchronized block. – MeBigFatGuy Apr 29 '11 at 05:12
  • Yeah I was just trying to simplify it to show the question at hand. Whats weird is the behavior that I am seeing is that if I lock from within A I can actually lock it at the same time in B. Which pretty much means the synchronized has no effect. Which is why I surmised that maybe locking a reference won't work. – w.donahue Apr 29 '11 at 05:40

2 Answers2

6

It synchronizes on A's list. What do you mean by B's reference to A's list? It doesn't matter if you're in A using list or B using A.getList(), they both reference the same object. When you synchronize on it you'll block other threads from synchronizing on that same object, regardless of where it's referenced from.

WhiteFang34
  • 70,765
  • 18
  • 106
  • 111
1

The OP followed up with this comment:

What's weird is the behavior that I am seeing is that if I lock from within A I can actually lock it at the same time in B. Which pretty much means the synchronized has no effect. Which is why I surmised that maybe locking a reference won't work.

That can't happen with the code in the question.

But it could happen if there was a setList method in A that updated the list variable. You could then end up in a situation where the two threads were locking on different objects.

Another possibility is that you actually only have one thread that is taking a lock on the same object twice. That's normal behavior. Java primitive mutexes are reentrant; i.e. they only prevent two different threads from holding the same mutex at the same time.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • My code is locking a list, and in the lock adding a new element. Later it tries to relock when it calls a common function to find something in the list. This relock is deadlocking. While this is running there is a second thread that was able to get a lock on the list. Your point about if setList were called may explain the behavior i am seeing. If the two lists are different objects then I would think it is unsafe to synchronize on the list in the first place. Should I make a class just to manually lock this object and use that instead of synchronized keyword? – w.donahue Apr 29 '11 at 16:57