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.
要回答你的问题,仍然 Producer
和 Consumer
都可以 运行 使用 Q
,但是 get
和 put
方法永远不会同时执行,因为与带有关键字 synchronized
的对象实例隐式同步。
在任何给定时间,Producer
或 Consumer
只会执行一个方法,即当 get
被 Consumer
、Producer
调用时不能调用 put
,反之亦然。
我一直在阅读 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.
要回答你的问题,仍然 Producer
和 Consumer
都可以 运行 使用 Q
,但是 get
和 put
方法永远不会同时执行,因为与带有关键字 synchronized
的对象实例隐式同步。
在任何给定时间,Producer
或 Consumer
只会执行一个方法,即当 get
被 Consumer
、Producer
调用时不能调用 put
,反之亦然。