MyException - 我的异常网
当前位置:我的异常网» J2SE » 求教底下这个代码结果为什么是随机的

求教底下这个代码结果为什么是随机的(2)

www.MyException.Cn  网友分享于:2013-12-25  浏览:5次

------解决方案--------------------
因为你的CPU是双核的,线程会被随机的分配到每一个核里面去,又或者是随机的都出现在某一个核里面。
------解决方案--------------------
楼主代码有点问题,不能够用if来作为wait的判断,这样下面的代码notifyAll()后也不会执行的,参考下下面的代码
Java code

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);这两段代码间随时都有可能有其他线程插入了,这也必须得同步。
你参考下下面的代码吧,可以达到你的要求
Java code

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

------解决方案--------------------
Java code

//理解错了,终于明白楼主要干嘛,你把它改成这样吧,就能严格按照顺序输出

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

文章评论

软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有