@Kaddy, you have two problems with the code you posted:
- You have multiple instances of UI, and
- Your locking is per-method, but it appears you want to lock across methods.
Let me explain both. First, a really quick explanation of synchronized. Consider this code:
class MyClass {
synchronized void myMethod() {
// do something
}
}
This is essentially shorthand for:
class MyClass {
void myMethod() {
synchronized (this) {
// do something
}
}
}
How synchronized works is that if multiple threads try to sync on the same instance, then only one is allow inside the sync block at a time. When thread that did go inside leaves the block -- either through regular execution or because of exception -- then one of the remaining threads is allowed to enter its sync block. This goes on until no threads are trying to acquire a lock on that instance.
So to your first problem: each thread has its own instance of Ui. So the threads are sync'ing on different instances. You can fix that problem in two ways.
Either share one instance of Ui:
UI ui = new UI();
RunnableUI rm1 = new RunnableUI(ui);
RunnableUI rm2 = new RunnableUI(ui);
Or lock on something other than the UI instance:
class UI {
private static final Object LOCK = new Object();
public Object getLock() {
return LOCK;
}
public void update() {
synchronized (getLock()) {
// do something
}
}
...
}
To your second problem. You are not locking broadly enough. If you opt for a shared UI instance, try this:
class RunnableUI implements Runnable {
private final UI _ui;
RunnableUI(UI ui) {
_ui = ui;
}
public void run() {
synchronized (_ui) {
_ui.update(20);
_ui.stop();
}
}
}
If you opt for a shared lock, try this:
class RunnableUI implements Runnable {
public void run() {
UI ui = new UI();
synchronized (ui.getLock()) {
ui.update(20);
ui.stop();
}
}
}