Java线程程序在Eclipse中工作,但不在终端/命令提示符下工作
这段代码在eclipse中运行良好,但在命令提示符或终端中运行不好。任何帮助都将不胜感激,因为我不知道为什么它不起作用。它在Eclipse中一直运行,但在命令提示符下执行时挂起 Producer类生成随机double并调用add,而Consumer类调用pop;两人都打了1000000次电话 Buffer.javaJava线程程序在Eclipse中工作,但不在终端/命令提示符下工作,java,eclipse,Java,Eclipse,这段代码在eclipse中运行良好,但在命令提示符或终端中运行不好。任何帮助都将不胜感激,因为我不知道为什么它不起作用。它在Eclipse中一直运行,但在命令提示符下执行时挂起 Producer类生成随机double并调用add,而Consumer类调用pop;两人都打了1000000次电话 Buffer.java public class Buffer{ private double[] buf; private int next = 0; private int start = 0; pr
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");
}
}
您需要同步到pop和add方法。我认为这应该解决这个问题 我也不知道,因为你没有定义不工作。编译错误、运行时异常、逻辑错误?我们可以得到神奇的8-ball,但我怀疑它会有多大帮助。老实说,你可能想看看java线程的教程。这段代码在eclipse中工作的事实并不一定就是运气。为了澄清/重新表述@Brian Roach所说的,这段代码在任何地方都能工作的事实完全是运气。您没有使用有效的线程同步机制,因此程序的行为完全未定义。否,bwait无效。请阅读一些关于线程和更改可见性的文章。在任何线程同步操作之外,一个线程所做的更改不需要对任何其他线程可见。因此,生产者和消费者都可以随心所欲地修改信号量值,至少不会看到彼此的变化,这是一种可能的行为。