Java 监视器中的同步方法

Synchronized method in Java monitor

我目前正在学习 Java 中 monitor 的使用,但我不知道 synchronized 方法是如何工作的。

我知道当一个线程在同步方法中时,另一个线程不能在同步方法中并且睡眠不会取消监视器自己的所有权。

所以我试着写了一个代码来测试

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();
}
}

我认为 nbA 或 nbB 不可能优于 1 或者 nbB 和 nbA 都 >0 但它正在发生

我误会了什么?

抱歉英语不好。

您在不同的对象上同步:synchronized 非静态方法在 this 上同步,因此每个 new ex3() 实例有效地工作就像它没有同步一样。

同步实例方法完全等同于:

public void A() {
    synchronized (this) {
        // The body.
    }
}

要么制作同步方法 static,要么在 class(或其他共享对象)上显式同步:

public void A() throws InterruptedException{
    synchronized (ex3.class) {
        nbA++;
        Thread.sleep(rand.nextInt(500));
        nbA--;
    }
}

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.

正确。

NB Per Brinch Hansen 认为 Java 没有显示器,但他发明了它们。