好的,这是密码。它基本上有三个类。其中一个是增加一个值,另一个是减少一个无休止的循环。但当数值超过或低于某一特定极限时,它必须停止。但由于这两个函数都有notifyall,所以它也会唤醒其他函数,因此即使它处于极限,它也会继续运行。我怎样才能解决这个问题?提前谢谢。
第一类(增加和使用线程):
public class Producer extends Thread{
private Counter counter;
public Producer(Counter counter) {
// TODO Auto-generated constructor stub
this.counter=counter;
}
@Override
public void run() {
// TODO Auto-generated method stub
//super.run();
for(;;) {
try {
counter.increase();
sleep(100);
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("Producer:"+e.getMessage());
}
}
}
第二类(随runnable递减):
public class Consumer implements Runnable{
private Counter counter;
public Consumer(Counter counter) {
// TODO Auto-generated constructor stub
this.counter=counter;
}
@Override
public void run() {
// TODO Auto-generated method stub
//super.run();
for(;;) {
try {
counter.decrease();
Thread.currentThread().sleep(100);
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("Consumer:"+e.getMessage());
}
}
}
}
包含函数的第三类:
import java.util.Random;
public class Counter {
private int counter;
private Random ran;
public Counter() {
//super();
counter=0;
ran= new Random();
}
public synchronized void increase() {
int number=ran.nextInt(5);
if(counter+number>=100 ) {
System.out.println("Producer is stopping, value is: "+counter);
System.out.println("The generated number is: "+number);
try {
wait();
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("error in increasing mehtod"+e.getMessage());
}
}
counter = counter+number;
notifyAll();
System.out.println("Prdoucer increase: "+counter);
}
public synchronized void decrease() {
int number= ran.nextInt(5);
if(counter-number<0) {
System.out.println("Consumer is stopping, value is: "+counter);
System.out.println("The generated number is: "+number);
try {
wait();
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("error in decreasing mehtod"+e.getMessage());
}
}
counter = counter-number;
notifyAll();
System.out.println("Consumer decrease: "+counter);
}
}
2条答案
按热度按时间vulvrdjw1#
阅读虚假通知。即使没有显式调用notify()/notifyall(),也可以通知线程。因此,在每次通知之后,线程必须检查它是否确实收到了通知,并准备好发现它收到的通知是徒劳的。
7rtdyuoh2#
.如何使用
notifyAll()
对于特定线程。你没有。不是这样的
notifyAll()
是为了,不是为了什么notify()
两个都是。你用
notify()
和/或notifyAll()
通知其他线程某些特定的事情已经改变或发生。你用notify()
当保证捕获通知的任何单个线程都能够处理更改或发生的任何事情时。你用notifyAll()
否则。在这两种情况下,调用者都不能指定应该通知哪些线程。系统将随机选择任何一个线程,该线程恰好在
o.wait()
如果你打电话,就打电话o.notify()
对于同一对象o
,否则它将通知所有正在等待的线程o.wait()
如果你打电话o.notifyAll()
. 它不会为尚未在应用程序中的线程执行任何操作o.wait()
打电话的时候o.notify()
或者o.notifyAll()
被叫来了。由您自己编写代码来利用这些函数为您带来好处。关于如何做到这一点,有很多例子和教程。我个人最喜欢的:https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
另请注意:正确使用
notify()
以及notifyAll()
有点棘手。正确地编写代码对您来说很棘手,而对其他想阅读和理解您的代码的人来说也很棘手。如果你认为你需要
notify()
或者notifyAll()
您应该做的第一件事是考虑是否可以使用更高级别的类来封装notify/wait行为。e、 例如,对于“生产者/消费者”体系结构,您可以考虑使用BlockingQueue
.