I am currently learning the use of monitor in Java, but i do not know how the synchronized methods work.
I understand that while one thread is inside a synchronized method, another thread cannot be inside a synchronized method and that sleep doesn't take off the monitor's own ownership.
So i tried to write a code to test that
import java.util.Random;
public class ex3 extends Thread {
private static int nbA=0;
private static int nbB=0;
public static final Random rand = new Random();
public void run(){
while(true){
System.out.println(nbA+" "+nbB);
try{
Thread.sleep(rand.nextInt(500));
}catch (Exception e ){e.printStackTrace();}
if (rand.nextBoolean()){
try {
A();
} catch (InterruptedException e) {}
}else{
try {
B();
} catch (InterruptedException e) {}
}
}
}
public synchronized void A() throws InterruptedException{
nbA++;
Thread.sleep(rand.nextInt(500));
nbA--;
}
public synchronized void B() throws InterruptedException{
nbB++;
Thread.sleep(rand.nextInt(500));
nbB--;
}
public static void main(String[] argv){
new ex3().start();
new ex3().start();
new ex3().start();
}
}
You're synchronizing on different objects: a synchronized
non-static method synchronizes on this
, so each of the new ex3()
instances effectively works like it's not synchronized.
A synchronized instance method is exactly equivalent to this:
public void A() {
synchronized (this) {
// The body.
}
}
Either make the synchronized methods static
, or explicitly synchronize on the class (or something other shared object):
public void A() throws InterruptedException{
synchronized (ex3.class) {
nbA++;
Thread.sleep(rand.nextInt(500));
nbA--;
}
}