求教下面这个代码结果为什么是随机的?
在学同步时候练习用的
目的是:pro put 0
con get 0
pro put 1
con get 1
...
但是做出来后发现运行结果是随机的~虽然有时候能对上
求教错在哪里?
我怀疑两个synchronized方法是不是用的一个this的锁
但是我看不出怎么改
求教求教
代码如下:
public class Wait
{
public static void main(String[] args)
{
Queue q = new Queue();
Producer pro = new Producer(q);
Consumer con = new Consumer(q);
pro.start();
con.start();
}
}
class Queue
{
int value;
boolean full = false;
public synchronized void input(int i)
{
if(!full)
{
value=i;
full=true;
notify();
}
else
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public synchronized int output()
{
if(!full)
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
else
{
full = false;
notify();
}
return value;
}
}
class Producer extends Thread
{
Queue q;
Producer(Queue q)
{
this.q = q;
}
public void run()
{
for(int i=0;i<10;i++)
{
q.input(i);
System.out.println("Producer input "+i);
}
}
}
class Consumer extends Thread
{
Queue q;
Consumer(Queue q)
{
this.q = q;
}
public void run()
{
while(true)
{
System.out.println("Consumer get "+q.output());
}
}
}
[解决办法]
public class Wait { public static void main(String[] args) { Queue q = new Queue(); Producer pro = new Producer(q); Consumer con = new Consumer(q); pro.start(); con.start(); }}class Queue { int value; boolean full = false; public synchronized void input(int i) { if (!full) { value = i; full = true; notify(); } else { try { wait(); } catch (Exception e) { e.printStackTrace(); } } } public synchronized int output() { if (!full) { try { wait(); } catch (Exception e) { e.printStackTrace(); } } else { full = false; notify(); } return value; }}class Producer extends Thread { Queue q; Producer(Queue q) { this.q = q; } public void run() { for (int i = 0; i < 10; i++) { synchronized (this) { while (q.full == true); q.input(i); System.out.println("Producer input " + i); } } }}class Consumer extends Thread { Queue q; Consumer(Queue q) { this.q = q; } public void run() { while (true) { synchronized (this) { while (q.full == false) ; int temp = q.output();//这里顺便将值保存起来,以便退出这个线程,否则你的CPU很生气 System.out.println("Consumer get " + temp); if(temp >=9) System.exit(0); } } }}
[解决办法]
因为你的CPU是双核的,线程会被随机的分配到每一个核里面去,又或者是随机的都出现在某一个核里面。
[解决办法]
楼主代码有点问题,不能够用if来作为wait的判断,这样下面的代码notifyAll()后也不会执行的,参考下下面的代码
public class Wait { public static void main(String[] args) { Queue q = new Queue(); Producer pro = new Producer(q); Consumer con = new Consumer(q); pro.start(); con.start(); }}class Queue { int value; boolean full = false; public synchronized void input(int i) { while (full) { try { wait(); } catch (Exception e) { e.printStackTrace(); } } value = i; full = true; notify(); } public synchronized int output() { while (!full) { try { wait(); } catch (Exception e) { e.printStackTrace(); } } full = false; notify(); return value; }}class Producer extends Thread { Queue q; Producer(Queue q) { this.q = q; } public void run() { for (int i = 0; i < 10; i++) { q.input(i); System.out.println("Producer input " + i); } }}class Consumer extends Thread { Queue q; Consumer(Queue q) { this.q = q; } public void run() { while (true) { System.out.println("Consumer get " + q.output()); } }}
[解决办法]
因为System.out.println()打印语句没有被同步,所以虽然运行结果正常,但是打印的结果仍然不是实际运行结果
[解决办法]
请问你是要代码还是要思路?5楼的代码是展示如何同步队列的存取,你先前的存取都存在问题,至于打印的结果不是你要的是由于
q.input(i);
System.out.println("Producer input "+i);这两段代码间随时都有可能有其他线程插入了,这也必须得同步。
你参考下下面的代码吧,可以达到你的要求
public class Wait { public static void main(String[] args) { Queue q = new Queue(); Producer pro = new Producer(q); Consumer con = new Consumer(q); con.setDaemon(Boolean.TRUE.booleanValue()); pro.start(); con.start(); }}class Queue { int value; boolean full = false; public synchronized void input(int i) { while (full) { try { wait(); } catch (Exception e) { e.printStackTrace(); } } value = i; full = true; System.out.println("Producer input " + value); notify(); } public synchronized int output() { while (!full) { try { wait(); } catch (Exception e) { e.printStackTrace(); } } full = false; System.out.println("Consumer get " + value); notify(); return value; }}class Producer extends Thread { Queue q; Producer(Queue q) { this.q = q; } public void run() { for (int i = 0; i < 10; i++) { q.input(i); } }}class Consumer extends Thread { Queue q; Consumer(Queue q) { this.q = q; } public void run() { while (true) { q.output(); } }}
[解决办法]
//理解错了,终于明白楼主要干嘛,你把它改成这样吧,就能严格按照顺序输出import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Wait3 { public static void main(String[] args) { new Queue(); }}class Queue {//既然都涉及full和value,那就把它作為大管家吧,建立exec统一管理生产者,消费者 int value; boolean full = false; ExecutorService exec = Executors.newCachedThreadPool();// Consumer consumer = new Consumer(this); Producer producer = new Producer(this); public Queue() { exec.execute(consumer); exec.execute(producer); } public synchronized void input(int i) { full = true; value = i; } public synchronized int output() { if (value == 10)//生产消费完 就退出生产者和消费者 exec.shutdownNow(); full = false; return value; }}/////////////////////////////////////////////////////////////////////////////class Producer extends Thread { Queue q; private int i = -1; Producer(Queue q) { this.q = q; } public void run() { try { while (!Thread.interrupted()) { synchronized (this) { while (q.full == true) wait();// 等待 i++; synchronized (q.consumer) {//软禁消费者 q.input(i); System.out.println("Producer input " + i); q.consumer.notifyAll();//唤醒 } } } } catch (Exception e) { } }}// ///////////////////////////////////////////////////////class Consumer extends Thread { Queue q; Consumer(Queue q) { this.q = q; } public void run() { try { while (!Thread.interrupted()) { synchronized (this) { while (q.full == false) wait();// 等待 } synchronized (q.producer) {//软禁生产者 System.out.println("Consumer get " + q.output()); q.producer.notifyAll();//唤醒 } } } catch (Exception e) { } }}
[解决办法]
LZ经过了多次测试,是你想要的结果,你的程序有两个问题1是不要用if判断线程是否等待,等待最好加this.wait(),先判断是否要等待(满足等待的条件就阻塞后面的语句不执行)2是System.out.println()这句没有同步,要写在同步方法里
public class Wait { public static void main(String[] args) { Queue q = new Queue(); (new Producer(q)).start(); (new Consumer(q)).start(); }}class Queue { int value;// 类比一个篮子(共享变量) boolean full = false;// 篮子空的 public synchronized void input(int i) { while (full == true)//满足等待条件线程等待,后面语句不执行 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } value = i;// 篮子空了,value获得一个值 System.out.println("Pruducer put " + i); full = true;// 篮子满了 notify(); } public synchronized void output() { while (full == false) try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Consumer get " + value); full = false;// 否则篮子置为空 notify();// 唤醒其他线程 }}class Producer extends Thread { Queue q; Producer(Queue q) { this.q = q; } public void run() { for (int i = 0; i < 10; i++) { q.input(i); } }}class Consumer extends Thread { Queue q; Consumer(Queue q) { this.q = q; } public void run() { while (true) { q.output(); } }}//结果Pruducer put 0Consumer get 0Pruducer put 1Consumer get 1Pruducer put 2Consumer get 2Pruducer put 3Consumer get 3Pruducer put 4Consumer get 4Pruducer put 5Consumer get 5Pruducer put 6Consumer get 6Pruducer put 7Consumer get 7Pruducer put 8Consumer get 8Pruducer put 9Consumer get 9