我使用wait和notifyAll在java中为连续的Producer-Consumer编写了下面的代码,在第二次迭代等待后执行失败并通知抛出
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;
}
}
答案 0 :(得分:0)
Scanner.nextLine()
会抛出noSuchElementException
。由于您在循环中运行,因此Scanner
会占用所有输入,然后找不到下一行并抛出异常。修复是在每次循环之前检查下一行。