线程间通信生产者消费者问题
Interthread communication Producer Consumer Problem
我正在尝试使用具有以下代码的线程执行一些生产者消费者 poc,并且在一轮之后两个线程都处于等待状态。
但我希望它们继续循环,其中一个线程不断增加计数器而另一个线程不断减少。
任何人都可以建议我缺少什么吗?
public class ProducerConsumerWithThreads {
synchronized void withdrawBoxConsumer() {
if(box > 0){
box --;
System.out.println("Took one box now boxes left "+ box);
}
if(box == 0) {
System.out.println("Please put more boxes");
notify();
try{wait();}catch(Exception e){
System.out.println("Exception occured" + e.fillInStackTrace());
}
} else {
withdrawBoxConsumer();
}
}
synchronized void putBoxProducer() {
if(box < 10){
box ++;
System.out.println("Put one box now boxes are "+ box);
}
if(box == 10) {
System.out.println("Please Consume boxes");
notify();
try{wait();}catch(Exception e){
System.out.println("Exception occured" + e.fillInStackTrace());
}
} else {
putBoxProducer();
}
}
public int box = 5;
public static void main(String[] args) throws InterruptedException {
//pipeline of 10 boxes
//consumer takes one at a time .. till its empty
int boxLimit = 10;
final int box = 5;
final ProducerConsumerWithThreads c=new ProducerConsumerWithThreads();
new Thread(){
public void run(){c.withdrawBoxConsumer();}
}.start();
new Thread(){
public void run(){c.putBoxProducer();}
}.start();
}
}
我得到的输出是:
Took one box now boxes left 4
Took one box now boxes left 3
Took one box now boxes left 2
Took one box now boxes left 1
Took one box now boxes left 0
Please put more boxes
Put one box now boxes are 1
Put one box now boxes are 2
Put one box now boxes are 3
Put one box now boxes are 4
Put one box now boxes are 5
Put one box now boxes are 6
Put one box now boxes are 7
Put one box now boxes are 8
Put one box now boxes are 9
Put one box now boxes are 10
Please Consume boxes
我希望它能按照逻辑进一步循环!有人可以帮忙吗?
你遇到的问题是一个非常基本的流程问题:当调用 'notify' 并且等待的线程再次启动时,该方法完成并且线程停止 运行ning。
请注意,您的两个方法都在同一个对象上同步,因此它们绝不会同时 运行。例如。一个线程将获得监视器和 increment/decrement 盒子,直到它最终等待。然后另一个线程会去,直到它等待。
您还有其他一些在使用等待和通知时很常见的问题。
synchronized void withdrawBoxConsumer() {
while( !Thread.currentThread().isInterrupted() ) {
if(box > 0){
box --;
System.out.println("Took one box now boxes left "+ box);
}
while(box == 0) {
System.out.println("Please put more boxes");
notifyAll();
try{
wait();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
}
synchronized void putBoxProducer() {
while( !Thread.currentThread().isInterrupted() ) {
if(box < 10){
box ++;
System.out.println("Put one box now boxes are "+ box);
}
while(box == 10) {
System.out.println("Please Consume boxes");
notifyAll();
try{
wait();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
}
- 我让它成为非递归的,因为你这样做的方式,堆栈会溢出。
- 由于虚假唤醒,等待条件处于循环中。
- 我改成了
notifyAll
notify只会唤醒一个等待线程,这样应该没问题,但还是保险起见。
box
理想情况下应该是并发的 class 或可变的,但由于您始终使用同步方法工作,所以应该没问题。
- 同样
box++
和 box--
是竞争条件。
e.fillInStackTrace()
不是您要使用的。
public class ProducerConsumerWithThreads {
synchronized void withdrawBoxConsumer() {
if(box > 0){
box --;
System.out.println("Took one box now boxes left "+ box);
}
if(box == 0) {
System.out.println("Please put more boxes");
notify();
try{wait();}catch(Exception e){
System.out.println("Exception occured" + e.fillInStackTrace());
}
}
withdrawBoxConsumer();
}
synchronized void putBoxProducer() {
if(box < 10){
box ++;
System.out.println("Put one box now boxes are "+ box);
}
if(box == 10) {
System.out.println("Please Consume boxes");
notify();
try{wait();}catch(Exception e){
System.out.println("Exception occured" + e.fillInStackTrace());
}
}
putBoxProducer();
}
public int box = 5;
public static void main(String[] args) throws InterruptedException {
//pipeline of 10 boxes
//consumer takes one at a time .. till its empty
int boxLimit = 10;
final int box = 5;
final ProducerConsumerWithThreads c=new ProducerConsumerWithThreads();
new Thread(){
public void run(){c.withdrawBoxConsumer();}
}.start();
new Thread(){
public void run(){c.putBoxProducer();}
}.start();
}
}
我正在尝试使用具有以下代码的线程执行一些生产者消费者 poc,并且在一轮之后两个线程都处于等待状态。 但我希望它们继续循环,其中一个线程不断增加计数器而另一个线程不断减少。
任何人都可以建议我缺少什么吗?
public class ProducerConsumerWithThreads {
synchronized void withdrawBoxConsumer() {
if(box > 0){
box --;
System.out.println("Took one box now boxes left "+ box);
}
if(box == 0) {
System.out.println("Please put more boxes");
notify();
try{wait();}catch(Exception e){
System.out.println("Exception occured" + e.fillInStackTrace());
}
} else {
withdrawBoxConsumer();
}
}
synchronized void putBoxProducer() {
if(box < 10){
box ++;
System.out.println("Put one box now boxes are "+ box);
}
if(box == 10) {
System.out.println("Please Consume boxes");
notify();
try{wait();}catch(Exception e){
System.out.println("Exception occured" + e.fillInStackTrace());
}
} else {
putBoxProducer();
}
}
public int box = 5;
public static void main(String[] args) throws InterruptedException {
//pipeline of 10 boxes
//consumer takes one at a time .. till its empty
int boxLimit = 10;
final int box = 5;
final ProducerConsumerWithThreads c=new ProducerConsumerWithThreads();
new Thread(){
public void run(){c.withdrawBoxConsumer();}
}.start();
new Thread(){
public void run(){c.putBoxProducer();}
}.start();
}
}
我得到的输出是:
Took one box now boxes left 4
Took one box now boxes left 3
Took one box now boxes left 2
Took one box now boxes left 1
Took one box now boxes left 0
Please put more boxes
Put one box now boxes are 1
Put one box now boxes are 2
Put one box now boxes are 3
Put one box now boxes are 4
Put one box now boxes are 5
Put one box now boxes are 6
Put one box now boxes are 7
Put one box now boxes are 8
Put one box now boxes are 9
Put one box now boxes are 10
Please Consume boxes
我希望它能按照逻辑进一步循环!有人可以帮忙吗?
你遇到的问题是一个非常基本的流程问题:当调用 'notify' 并且等待的线程再次启动时,该方法完成并且线程停止 运行ning。
请注意,您的两个方法都在同一个对象上同步,因此它们绝不会同时 运行。例如。一个线程将获得监视器和 increment/decrement 盒子,直到它最终等待。然后另一个线程会去,直到它等待。
您还有其他一些在使用等待和通知时很常见的问题。
synchronized void withdrawBoxConsumer() {
while( !Thread.currentThread().isInterrupted() ) {
if(box > 0){
box --;
System.out.println("Took one box now boxes left "+ box);
}
while(box == 0) {
System.out.println("Please put more boxes");
notifyAll();
try{
wait();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
}
synchronized void putBoxProducer() {
while( !Thread.currentThread().isInterrupted() ) {
if(box < 10){
box ++;
System.out.println("Put one box now boxes are "+ box);
}
while(box == 10) {
System.out.println("Please Consume boxes");
notifyAll();
try{
wait();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
}
- 我让它成为非递归的,因为你这样做的方式,堆栈会溢出。
- 由于虚假唤醒,等待条件处于循环中。
- 我改成了
notifyAll
notify只会唤醒一个等待线程,这样应该没问题,但还是保险起见。 box
理想情况下应该是并发的 class 或可变的,但由于您始终使用同步方法工作,所以应该没问题。- 同样
box++
和box--
是竞争条件。 e.fillInStackTrace()
不是您要使用的。
public class ProducerConsumerWithThreads {
synchronized void withdrawBoxConsumer() {
if(box > 0){
box --;
System.out.println("Took one box now boxes left "+ box);
}
if(box == 0) {
System.out.println("Please put more boxes");
notify();
try{wait();}catch(Exception e){
System.out.println("Exception occured" + e.fillInStackTrace());
}
}
withdrawBoxConsumer();
}
synchronized void putBoxProducer() {
if(box < 10){
box ++;
System.out.println("Put one box now boxes are "+ box);
}
if(box == 10) {
System.out.println("Please Consume boxes");
notify();
try{wait();}catch(Exception e){
System.out.println("Exception occured" + e.fillInStackTrace());
}
}
putBoxProducer();
}
public int box = 5;
public static void main(String[] args) throws InterruptedException {
//pipeline of 10 boxes
//consumer takes one at a time .. till its empty
int boxLimit = 10;
final int box = 5;
final ProducerConsumerWithThreads c=new ProducerConsumerWithThreads();
new Thread(){
public void run(){c.withdrawBoxConsumer();}
}.start();
new Thread(){
public void run(){c.putBoxProducer();}
}.start();
}
}