在学同步时候练习用的 
目的是: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());
        }
    }
}

解决方案 »

  1.   


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

    }    }
    }
      

  2.   

    线程的执行顺序完全不受你的控制,当你调用start方法后,以后先执行那个后执行那个线程都是cpu觉得的(你没有设置线程优先级)。
      

  3.   

    楼主代码有点问题,不能够用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());
    }
    }
    }
      

  4.   

    我今天问了下老师 
    老师给的答复是因为 class Queue 没有被锁
    所以可能当执行到 boolean full = false 时时间片到期 切换到另一进程 
    另一进程 采用了 full=false 导致随机和出错 
      

  5.   

    因为System.out.println()打印语句没有被同步,所以虽然运行结果正常,但是打印的结果仍然不是实际运行结果
      

  6.   

    请问你是要代码还是要思路?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();
    }
    }
    }
      

  7.   


    你要怎样的结果呢?//一楼是参考生产者,消费者模型 改装楼主的程序,其中
    class Producer extends Thread {
        Queue q;
        Producer(Queue q) {
    this.q = q;
        }
        public void run() {
    for (int i = 0; i < 10; i++) {//在有限时间里,他只能生产10个产品
        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)//在有限条件里,他只能消费10个产品,消费完就滚
        System.exit(0);//安全退出程序
        }
    }
        }
    }
    /*
    Producer input 0
    Consumer get 0
    Producer input 1
    Producer input 2
    Consumer get 1
    Consumer get 2
    Producer input 3
    Consumer get 3
    Producer input 4
    Consumer get 4
    Producer input 5
    Consumer get 5
    Producer input 6
    Consumer get 6
    Producer input 7
    Consumer get 7
    Producer input 8
    Consumer get 8
    Producer input 9
    Consumer get 9
     */
      

  8.   


    //理解错了,终于明白楼主要干嘛,你把它改成这样吧,就能严格按照顺序输出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) {
    }
        }
    }
      

  9.   

    CPU的执行是随机的,所以结果是不确定的
      

  10.   

    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 0
    Consumer get 0
    Pruducer put 1
    Consumer get 1
    Pruducer put 2
    Consumer get 2
    Pruducer put 3
    Consumer get 3
    Pruducer put 4
    Consumer get 4
    Pruducer put 5
    Consumer get 5
    Pruducer put 6
    Consumer get 6
    Pruducer put 7
    Consumer get 7
    Pruducer put 8
    Consumer get 8
    Pruducer put 9
    Consumer get 9