使用Threads时输出错误

时间:2014-02-14 21:38:46

标签: java multithreading producer-consumer

我正在尝试使用有3个饮酒者的线程做一个小程序,如果他有程序中指定的3件事,每个人都会喝酒

他们每个人应该从三件事中的一件开始

这就是我所做的事情

import java.util.*;

import test.Producer.Consumer;

public class PC {
    public static void main(String[] args) {
        AllResource c = new AllResource("water");
        AllResource c2 = new AllResource("ice");
        AllResource c3 = new AllResource("glass");
        Producer p1 = new Producer(c, 1);   // One Producer which acting  as Server

        Consumer c1   = new Consumer(c, 1);        // Consumer = Drinker(s)
        Consumer con2 = new Consumer(c2, 2);
        Consumer con3 = new Consumer(c3, 3);


        p1.start(); 
        p1 = new Producer(c2, 2);
        p1.start(); 
        p1=new Producer(c3, 3);
        c1.start();
        con2.start();
        con3.start();
        }
    }    
    class AllResource {
        private String resource;
        private boolean avail = false;
        ArrayList availableReource=new ArrayList();

        AllResource(String value){
            resource=value;        
        }       
        public boolean getAvail() {
               return avail;
        }
        public void setAvail(boolean avail1) {
               avail=avail1;
        }
        public synchronized String get(String value,boolean a, int number) {
            vail=a;

            if (avail == false) {
                resource=value;
                try {
                    wait();
                }
                catch (InterruptedException e) {

                }
            }
            else {
                resource=value;
                avail = false;
                notifyAll();
            }
            return resource;
        }
        public String getResource() {
            return resource;
        }
        public synchronized void put(String value, boolean a) {       
            avail=a;
            if (avail == true) {
                resource=value;
                try {
                    wait();
                }
                catch (InterruptedException e) { 

                } 
            }
            else {
                resource = value;
                avail = true;
                notifyAll();
           }
        }
    }
    class Producer extends Thread {
        private AllResource allResource;
        private int number;
        String resource[]={"water", "ice", "glass"};
        ArrayList al=new ArrayList();

        public Producer(AllResource c, int number) {
            allResource = c;
            this.number = number;
            al.add(c.getResource());
        }   
        public void run() {         
            while(true) {
                int rand=0;
                for(int j=0;j<resource.length;j++) {
                    rand=(int)(Math.random() * 3);
                    if(allResource.getResource()==(resource[rand])) {
                        allResource.put("",true);
                    }
                    else {
                        allResource.put(resource[rand],false); 
                    }   
                    System.out.println("Server #" + " put: "
                    + resource[rand] + " for Drinker "+this.number);   
                } 
            }
        }
        class Consumer extends Thread {
            private AllResource allResource;
            private int number;
            String resource[]={"water", "ice", "glass"};

            public Consumer(AllResource c, int number) {
                allResource = c;
                this.number = number;
            }
            public void run() {  
                while(true) {
                    for(int j=0;j<resource.length;j++) {
                        if(allResource.getResource().equals(resource[j])) {
                            allResource.get("",false,this.number);
                        }    
                        else {
                            allResource.get((String)resource[j],true,this.number);
                        }
                        System.out.println("Drinker  #" + this.number + " received: " + resource[j]);
                    }
                }
            }
        }      
    } 

由于某种原因,我收到错误的输出 这是输出的一部分

Server # put: glass for Drinker 1
Drinker  #3 received: water // drinker #3 received water even though there is no water provided for anyone
Drinker  #3 received: ice // drinker 3 received ice even though there is no ice provided for anyone
Server # put: ice for Drinker 2  
Drinker  #2 received: water // drinker 2 should receive ice not water
Server # put: glass for Drinker 2
Drinker  #3 received: glass // drinker 2 should receive glass not drinker 3 !
Server # put: glass for Drinker 1
Drinker  #1 received: water // it should receive glass not water
Server # put: ice for Drinker 1

// and now it's receiving lots of things and the server is not providing anything for him !
Drinker  #3 received: water
Drinker  #3 received: ice
Drinker  #3 received: glass
Drinker  #3 received: water

// same thing
Server # put: water for Drinker 2
Drinker  #2 received: ice
Drinker  #3 received: ice
Drinker  #1 received: ice

有人可以帮我吗?我不知道为什么会出现这些逻辑错误

1 个答案:

答案 0 :(得分:0)

我没有完全分析代码,但以下内容足以解释您获得的第一个“错误”:

String resource[]={"water", "ice", "glass"};

public void run() {  
    while(true) {
        for (int j = 0; j < resource.length; j++) {
            // removed irrelevant code   
            System.out.println("Drinker  #" + this.number + " received: " + resource[j]);
        }
    }
}

所以,你不打印饮酒者收到的东西。您正在打印包含所有三种资源的数组的每个元素。

我第一眼看到的另一个问题是你不尊重Object.wait()的javadoc中强制要求的惯用语,它应该总是在循环中调用。

您不应该使用wait()notifyAll(),它们是复杂的,非常低级别的方法。使用java.util.concurrent包中的更高级别并发对象,如BlockingQueue,它们易于使用,非常适合生产者/消费者问题。