Reputation: 301
Simply put, I'm wondering if this changes the behavior. I'm assuming yes, because calling someMethod() will lock the entire object, instead of just the list object? But I'm still new to this synchronization stuff, so I'd like some more educated feedback.
The before:
public void run() {
int i = 0;
while (!end) {
synchronized (list) {
while (list.size() == i) {
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
The After:
public void run() {
int i = 0;
while (!end) {
synchronized (list) {
while (list.size() == i) {
someMethod();
}
}
}
}
public synchronized void someMethod() {
try {
list.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Upvotes: 0
Views: 73
Reputation: 37960
You are correct - the new code has got different semantics, as someMethod()
is indeed synchronized on the instance it is being invoked on (and as such, that synchronization is entirely unrelated to the one on list
). However, the call to someMethod()
will take place while the monitor on list
is being held, so a call to run()
is "equally thread safe" with respect to list
.
On the other hand, you have now introduced the possibility for multiple threads to call someMethod()
directly at the same time. You have also introduced a (probably unnecessary) potential for deadlock with other threads due to the extra synchronization on the object itself. I would recommend this instead:
public void someMethod() {
synchronized (list) {
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
This method is now safe both for individual use and for being called through run()
- note that it is safe to synchronize on an object that you have already synchronized on; the thread won't block itself.
Upvotes: 2
Reputation: 4430
With syncronized
you don't really 'lock' an object. You will just make sure that access from everyone who is synchronizing on that specific object is 'regulated' with a lock.
A synchronized method is synchronizing on this
.
That means, if you enter a syncronized
block on some object list
you can call a syncronized
method without a problem at first
Some things to be thought about:
This code doesn't produce a deadlock:
public void foo() {
synchronized (this) {
someMethod();
}
}
public synchronized void someMethod() {
// ...
}
because you already have the "lock" on this
, but this:
public void foo() {
synchronized (list) {
someMethod();
}
}
public synchronized void someMethod() {
// ...
}
may produce a deadlock with some other thread! You'll have to be really careful if you enter a synchronized
section within another synchronized
section
Upvotes: 2