簡體   English   中英

生產者使用者在Java中使用線程

[英]Producer Consumer using threads in java

我已經使用wait和notifyAll在Java中編寫了連續的Producer-Consumer的以下代碼,第二次等待wait和notify throws之后執行失敗

Exception in thread "Thread-1" java.util.NoSuchElementException: No line found
    at java.util.Scanner.nextLine(Unknown Source)
    at com.sharedResource.ConsumerProducerQueue.addElements(ConsumerProducerQueue.java:48)
    at com.customRunnable.ProducerRunnable.run(ProducerRunnable.java:33)
    at java.lang.Thread.run(Unknown Source)

我的課程如下

package com.custom.datastructures;

public class Queue {

    private Link root;

    private boolean isConsumerWorking = true;
    private boolean isProducerWorking = true;
    private int count =0;

    public Link getRoot() {
        return root;
    }

    public void setRoot(Link root) {
        this.root = root;
    }

    public boolean isConsumerWorking() {
        return isConsumerWorking;
    }

    public void setConsumerWorking(boolean isConsumerWorking) {
        this.isConsumerWorking = isConsumerWorking;
    }

    public boolean isProducerWorking() {
        return isProducerWorking;
    }

    public void setProducerWorking(boolean isProducerWorking) {
        this.isProducerWorking = isProducerWorking;
    }

    public void push(int val)
    {
        if(root == null)
        {
            this.root = new Link(val);
            return;
        }

        Link tempCurr = root;
        Link prev = null;
        while(tempCurr != null)
        {
            prev = tempCurr;
            tempCurr = tempCurr.getNextLink();
        }

        prev.setNextLink(new Link(val));
        ++count;
        return;
    }

    public int pop()
    {
        if(root == null)
        {
            return -1;
        }

        Link tempCurr = root;
        Link next = tempCurr.getNextLink();
        root = next;
        --count;
        return tempCurr.getVal();
    }

    public boolean isEmpty()
    {
        return (root == null);
    }

}

**************************
package com.sharedResource;

import java.util.Scanner;

import com.custom.datastructures.Queue;

public class ConsumerProducerQueue {

    private Queue queue = new Queue();


    public Queue getQueue() {
        return queue;
    }

    public void setQueue(Queue queue) {
        this.queue = queue;
    }

    public synchronized void push(int val)
    {
        queue.push(val);
    }

    public synchronized int pop()
    {
        return queue.pop();
    }

    public boolean isEmpty()
    {
        return queue.isEmpty();
    }

    public synchronized void addElements()
    {
        Scanner sc = new Scanner(System.in);

        while(true)
        {
            System.out.println("Please input the value you want to add ");
            int val = 0;
            if(sc.hasNextInt())
            {
                val = sc.nextInt();
            }
            else{
                System.out.println(sc.nextLine());
            }
            System.out.println("The value entered by user is "+val);

            if(val == -1)
            {
                break;
            }

            queue.push(val);
        }
        sc.close();
        this.notifyAll();
    }

    public synchronized void displayElements() throws InterruptedException
    {
        if(queue.isEmpty())
        {
            this.wait();
        }

        while(!queue.isEmpty())
        {
            System.out.println(queue.pop());
            System.out.println();
        }

    }


}
*******************************
package com.customRunnable;

import com.sharedResource.ConsumerProducerQueue;

public class ConsumerRunnable implements Runnable {

    private ConsumerProducerQueue cpr = null;

    public ConsumerProducerQueue getCpr() {
        return cpr;
    }

    public void setCpr(ConsumerProducerQueue cpr) {
        this.cpr = cpr;
    }

     public ConsumerRunnable() {
        // TODO Auto-generated constructor stub
         this.cpr = new ConsumerProducerQueue();
    }

     public ConsumerRunnable(ConsumerProducerQueue cpr)
     {
         this.cpr = cpr;
     }

    @Override
    public void run() {
        try {
            while(true)
            {
                cpr.displayElements();
            }

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

*****************************
package com.customRunnable;

import java.util.Scanner;

import com.sharedResource.ConsumerProducerQueue;

public class ProducerRunnable implements Runnable {

    private ConsumerProducerQueue cpr = null;

    public ProducerRunnable()
    {
        this.cpr = new ConsumerProducerQueue();
    }

    public ProducerRunnable(ConsumerProducerQueue cpq)
    {
        this.cpr = cpq;
    }

    public ConsumerProducerQueue getCpr() {
        return cpr;
    }

    public void setCpr(ConsumerProducerQueue cpr) {
        this.cpr = cpr;
    }

    @Override
    public void run() {
        while(true)
        {
         cpr.addElements();
        }
    }

}

**********************
package com.custom.threadTester;

import com.customRunnable.ConsumerRunnable;
import com.customRunnable.ProducerRunnable;
import com.sharedResource.ConsumerProducerQueue;

public class ThreadTester2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ConsumerProducerQueue cpr = new ConsumerProducerQueue();
        ConsumerRunnable cr = new ConsumerRunnable(cpr);
        ProducerRunnable pr = new ProducerRunnable(cpr);

        Thread t1 = new Thread(cr);
        Thread t2 = new Thread(pr);

        t1.start();
        t2.start();

    }

}

Link.java類

package com.custom.datastructures;

        public class Link {

            public Link()
            {
                this.val = 12;
            }

            public Link(int val)
            {
                this.val = val;
            }

            private int val;

            private Link nextLink = null;

            public int getVal() {
                return val;
            }

            public void setVal(int val) {
                this.val = val;
            }

            public Link getNextLink() {
                return nextLink;
            }

            public void setNextLink(Link nextLink) {
                this.nextLink = nextLink;
            }

        }

當沒有下一行等待讀取時, Scanner.nextLine()會引發noSuchElementException 由於您正在循環中運行,因此Scanner用盡所有輸入,然后找不到下一行並拋出異常。 解決方法是每次循環時都在讀取前檢查下一行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM