java 中的监视器(信号量)

Monitor (semaphore) in java

我一直在阅读 Herbert Schildt 的 "The Complete Reference " 一书 java 并进行实践。
在这本书的线程章节中,有一节线程间通信。
一本手册说,在当前线程终止之前,任何线程都不会执行实例的其他同步方法,但请看下面的程序。
在输出中,它执行两个同步方法,有人怎么解释发生了什么?

输出:

put :0
put :1
put :2
put :3
put :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4
get :4

class Main{
    public static void main(String args[]){
        Q q=new Q();

        Producer p=new Producer(q);
        Consumer c=new Consumer(q); 
    }
}

class Q {
    int n;

    synchronized int get(){
        System.out.println("get :"+n);
        return n;
    }
    synchronized void put(int n){
        this.n=n;
        System.out.println("put :"+n);
    }
}



class Producer implements Runnable{
    Q q;
    Producer(Q q){
        this.q=q;
        new Thread(this,"Producer").start();

    }
    public void run(){
        int i=0;
        while(true){
            q.put(i++);
        }
    }
}

class Consumer implements Runnable{
    Q q;
    Consumer(Q q){
        this.q=q;
        new Thread(this,"Consumer").start();
    }

    public void run(){
        while(true){
            q.get();
        }
    }
}

Java docs

中提取

it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object

所以,终止意味着不是线程本身(例如:Consumer 不会等到 Producer 结束或完成,反之亦然),但是任何同步的执行完成 methods/blocks.

要回答你的问题,仍然 ProducerConsumer 都可以 运行 使用 Q,但是 getput 方法永远不会同时执行,因为与带有关键字 synchronized 的对象实例隐式同步。

在任何给定时间,ProducerConsumer 只会执行一个方法,即当 getConsumerProducer 调用时不能调用 put,反之亦然。