public class class_Q {
volatile boolean valueSet = false;
volatile int n;
synchronized int get()
{
System.out.println("Now i am in get block and valueset is : "+ valueSet );
if(!valueSet)
{
System.out.println("i am waiting in get block.....and releasing lock ");
try{
wait();
}catch(InterruptedException e)
{
System.out.println( "InterruptedException caught" );
}
}
System.out.println( " value of n now in get block is : " + n );
valueSet=false;
notify();
return n;
}
synchronized void put(int n)
{
System.out.println(" Now i am in Put block and valueset is : "+ valueSet);
if(valueSet)
{
try
{
System.out.println("i am waiting in put block......and releasing lock. ");
wait();
}catch(InterruptedException e)
{
System.out.println( "InterruptedException caught" );
}
}
this.n = n;
valueSet = true;
System.out.println( "the value of n now in put block is : " + n );
notify();
}
}
class Producer implements Runnable{
class_Q q;
Producer(class_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{
class_Q q;
Consumer(class_Q q)
{
this.q = q;
new Thread(this, "Consumer").start();
}
public void run()
{
while(true)
{
q.get();
}
}
}
class PCFixed {
public static void main (String args[])
{
class_Q q = new class_Q();
new Producer(q);
new Consumer(q);
System.out.println( "Press Control-C to stop." );
}
}
的 的 * OUTPUT **
现在我在get block和valueset中是:false
我正在等待阻止.....并释放锁定
按Control-C停止。
现在我在Put块中,而valueset是:false
现在在put块中的n的值是:0
现在在get块中的n值是:0
现在我在get block和valueset中是:false
我正在等待阻止.....并释放锁定
现在我在Put块中,而valueset是:false
现在在put块中的n的值是:1
现在在get块中的n值是:1
在输出的第六行之后,我期待get()线程唤醒(“notify()”)put()线程。有人可以帮助我理解调用get()线程背后的逻辑(换句话说,为什么它在get块?)
答案 0 :(得分:1)
我重新格式化了您的代码并更改了日志消息,因此所有内容都应该更加清晰。
public class Test {
static class class_Q {
volatile boolean valueSet = false;
volatile int n;
synchronized int get() throws InterruptedException {
System.out.println("get entering - valueSet=" + valueSet);
// *** Changed from `if` to `while`
while (!valueSet) {
System.out.println("get waiting");
wait();
}
// Clear to set the value.
valueSet = false;
// Tell any put waits to finish
notify();
System.out.println("get finished - n=" + n);
return n;
}
synchronized void put(int n) throws InterruptedException {
System.out.println("put entering - valueSet=" + valueSet);
// *** Changed from `if` to `while`
while (valueSet) {
System.out.println("put waiting");
wait();
}
this.n = n;
valueSet = true;
System.out.println("put finished - n=" + n);
notify();
}
}
static class Producer implements Runnable {
class_Q q;
Producer(class_Q q) {
this.q = q;
}
public void run() {
int i = 0;
try {
while (true) {
q.put(i++);
System.out.println("put(" + (i-1) + ")");
}
} catch (InterruptedException ex) {
// Just exit the run loop and finish when interrupted.
}
}
}
static class Consumer implements Runnable {
class_Q q;
Consumer(class_Q q) {
this.q = q;
}
public void run() {
try {
while (true) {
int i;
i = q.get();
System.out.println("get(" + i + ")");
}
} catch (InterruptedException ex) {
// Just exit the run loop and finish when interrupted.
}
}
}
public static void main(String args[]) {
class_Q q = new class_Q();
Thread producer = new Thread(new Producer(q));
Thread consumer = new Thread(new Consumer(q));
System.out.println("Press Control-C to stop.");
producer.start();
consumer.start();
}
}
我也做了三个主要的改变。我已经使interrupted
机制退出你的线程。我已将阻止测试循环设置为阻塞状态,而不仅仅是检查它们(while (x)
而不是if (x)
)。我让你的线程不能自动启动。
我认为如果您现在运行此代码,则流程应该更清晰,您应该能够更好地了解正在发生的事情。请记住,System.out
是PrintWriter
,因此可以进行缓冲。
我得到的输出是:
put entering - valueSet=false put finished - n=0 put(0) put entering - valueSet=true put waiting Press Control-C to stop. get entering - valueSet=true get finished - n=0 put finished - n=1 put(1) put entering - valueSet=true put waiting get(0) get entering - valueSet=true get finished - n=1 put finished - n=2 put(2) put entering - valueSet=true put waiting get(1) get entering - valueSet=true get finished - n=2 get(2) get entering - valueSet=false get waiting put finished - n=3 get finished - n=3 get(3) get entering - valueSet=false get waiting put(3) put entering - valueSet=false put finished - n=4 get finished - n=4 get(4) get entering - valueSet=false get waiting put(4) ...
答案 1 :(得分:0)
在输出的第六行之后,我期待get()线程唤醒(“notify()”)put()线程。有人可以帮助我理解调用get()线程背后的逻辑(换句话说,为什么它在get块?)
Producer start,call put,valueSet
为false,从函数返回,再次调用put,valueSet
为真所以他必须等待... get
中没有通知然后,即使消费者已经读取了写入的值,生产者也会被永久阻止......
每个中的notify
用于表示在该过程中前进的另一个参与者,并且正在等待后面的线程,它们现在都是同一个点。
答案 2 :(得分:0)
这是具有阻塞队列的经典生产者 - 消费者模式。如果队列已满,则生成将数据写入队列并阻塞(在队列的当前实现大小 - 单个元素中)。当队列为空时,消费者从队列中读取并阻塞(等待)。
1您使用valueSet = false调用get()。停在等待()。
2您调用put()来通知()您的队列对象并解锁在get()方法中等待的线程的执行。