简体   繁体   中英

Java thread program works in Eclipse, but not in terminal / command prompt

This code runs fine within eclipse, but not in command prompt (or terminal). Any help would be greatly appreciated, as I have no idea why it's not working. It runs all the way through in Eclipse, but hangs during execution in command prompt.

The Producer class generates random doubles and calls add(), while the Consumer class calls pop(); both call these 1,000,000 times.

Buffer.java

public class Buffer{

private double[] buf;
private int next = 0;
private int start = 0;
private int semaphore = 1;
private boolean isFull = false;
private boolean isEmpty = true;

public static void main(String[] args) {
    Buffer pcbuf = new Buffer(1000);
    Thread prod = new Thread (new Producer(pcbuf));
    Thread cons = new Thread (new Consumer(pcbuf));
    prod.start();
    cons.start();
}

public Buffer(int size){
    buf = new double[size];
}

private synchronized void bwait(){
    while(semaphore <= 0){}
    semaphore--;
}

private void bnotify(){
    semaphore++;
}

public void add(double toAdd){
    boolean hasAdded = false;
    while(!hasAdded){
        if(!isFull){
            bwait();
            buf[next] = toAdd;
            next=(next+1)%buf.length;
            if(next == start){
                isFull = true;
            }
            isEmpty = false;
            hasAdded = true;
            bnotify();
        }
    }
}

public double pop(){
    boolean hasPopped = false;
    double toReturn = 0.0;
    while(!hasPopped){
        if(!isEmpty){
            bwait();
            toReturn = buf[start];
            start=(start+1)%buf.length;
            if(start == next){
                isEmpty = true;
            }
            isFull = false;
            hasPopped = true;
            bnotify();
        }
    }
    return toReturn;
}
}

Producer.java

import java.text.DecimalFormat;
import java.util.Random;

public class Producer extends Thread{

private Buffer b;
private double bufferValueCounter = 0.0;
private int numProduced = 0;

public Producer(Buffer b){
    this.b = b;
}

public void run() {
    Random r = new Random();
    DecimalFormat df = new DecimalFormat("#,###");
    while (numProduced < 1000000){
        double toAdd = r.nextDouble() * 100.0;
        b.add(toAdd);
        bufferValueCounter+=toAdd;
        numProduced++;
        if(numProduced%100000==0){
            System.out.println("Producer: Generated " + df.format(numProduced) + " items, Cumulative value of generated items = " + bufferValueCounter);
        }
    }
    System.out.println("Producer: Finished generating 1,000,000 items");
}   
}

Consumer.java

import java.text.DecimalFormat;

public class Consumer extends Thread{

private Buffer b;
private double bufferValueCounter = 0.0;
private int numConsumed = 0;

public Consumer(Buffer b){
    this.b = b;
}

public void run(){
    DecimalFormat df = new DecimalFormat("#,###");
    while(numConsumed < 1000000){
        double popped = b.pop();
        bufferValueCounter += popped;
        numConsumed++;
        if(numConsumed%100000==0){
            System.out.println("Consumer: Consumed  " + df.format(numConsumed) + " items, Cumulative value of consumed items  = " + bufferValueCounter);
        }
    }
    System.out.println("Consumer: Finished consuming 1,000,000 items");
}
}

You need to synchronized to pop and add methods. I think that should fix the issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM