Java 生产者/消费者线程不会给出结果
我正在为我的操作系统课程做一个CPU调度模拟器项目。程序应该由两个线程组成:生产者线程和消费者线程。producer线程包括在系统中生成进程的生成器和选择多个进程并将它们放入称为ReadyQueue类型缓冲区的对象(这是使用者和生产者共享的对象)中的长期调度器。使用者线程包括短期调度器,它从队列中获取进程并启动调度算法。我在没有使用线程的情况下编写了整个程序,它工作正常,但现在我需要添加线程,我从来没有使用过线程,因此如果有人能告诉我如何修改下面显示的代码以实现所需的线程,我将不胜感激 下面是Producer类实现:Java 生产者/消费者线程不会给出结果,java,multithreading,producer-consumer,consumer,Java,Multithreading,Producer Consumer,Consumer,我正在为我的操作系统课程做一个CPU调度模拟器项目。程序应该由两个线程组成:生产者线程和消费者线程。producer线程包括在系统中生成进程的生成器和选择多个进程并将它们放入称为ReadyQueue类型缓冲区的对象(这是使用者和生产者共享的对象)中的长期调度器。使用者线程包括短期调度器,它从队列中获取进程并启动调度算法。我在没有使用线程的情况下编写了整个程序,它工作正常,但现在我需要添加线程,我从来没有使用过线程,因此如果有人能告诉我如何修改下面显示的代码以实现所需的线程,我将不胜感激 下面是P
public class Producer extends Thread{
ReadyQueue Buffer = new ReadyQueue(20); // Shared Buffer of size 20 between consumer and producer
JobScheduler js = new JobScheduler(Buffer);
private boolean systemTerminate = false; // Flag to tell Thread that there are no more processes in the system
public Producer(ReadyQueue buffer) throws FileNotFoundException{
Buffer = buffer;
Generator gen = new Generator(); // Generator generates processes and put them in a vector called memory
gen.writeOnFile();
}
@Override
public void run() {
synchronized(this){
js.select(); // Job Scheduler will select processes to be put in the Buffer
Buffer = (ReadyQueue) js.getSelectedProcesses();
while(!Buffer.isEmpty()){
try {
wait(); // When Buffer is empty wait until getting notification
} catch (InterruptedException e) {
e.printStackTrace();
}
systemTerminate = js.select();
Buffer = (ReadyQueue) js.getSelectedProcesses();
if(systemTerminate) // If the flag's value is true the thread yields
yield();
}
}
}
public ReadyQueue getReadyQueue(){
return Buffer;
}
}
public class Consumer extends Thread{
ReadyQueue Buffer = new ReadyQueue(20);
Vector<Process> FinishQueue = new Vector<Process>();
MLQF Scheduler ;
public Consumer(ReadyQueue buffer){
Buffer = buffer;
Scheduler = new MLQF(Buffer,FinishQueue); // An instance of the multi-level Queue Scheduler
}
@Override
public void run() {
int count = 0; // A counter to track the number of processes
while(true){
synchronized(this){
Scheduler.fillQueue(Buffer); // Take contents in Buffer and put them in a separate queue in the scheduler
Scheduler.start(); // Start Scheduling algorithm
count++;
}
if(count >= 200) // If counter exceeds the maximum number of processes thread must yeild
yield();
notify(); // Notify Producer thread when buffer is empty
}
}
public void setReadyQueue(ReadyQueue q){
Buffer = q;
}
}
这是消费者类实现:
public class Producer extends Thread{
ReadyQueue Buffer = new ReadyQueue(20); // Shared Buffer of size 20 between consumer and producer
JobScheduler js = new JobScheduler(Buffer);
private boolean systemTerminate = false; // Flag to tell Thread that there are no more processes in the system
public Producer(ReadyQueue buffer) throws FileNotFoundException{
Buffer = buffer;
Generator gen = new Generator(); // Generator generates processes and put them in a vector called memory
gen.writeOnFile();
}
@Override
public void run() {
synchronized(this){
js.select(); // Job Scheduler will select processes to be put in the Buffer
Buffer = (ReadyQueue) js.getSelectedProcesses();
while(!Buffer.isEmpty()){
try {
wait(); // When Buffer is empty wait until getting notification
} catch (InterruptedException e) {
e.printStackTrace();
}
systemTerminate = js.select();
Buffer = (ReadyQueue) js.getSelectedProcesses();
if(systemTerminate) // If the flag's value is true the thread yields
yield();
}
}
}
public ReadyQueue getReadyQueue(){
return Buffer;
}
}
public class Consumer extends Thread{
ReadyQueue Buffer = new ReadyQueue(20);
Vector<Process> FinishQueue = new Vector<Process>();
MLQF Scheduler ;
public Consumer(ReadyQueue buffer){
Buffer = buffer;
Scheduler = new MLQF(Buffer,FinishQueue); // An instance of the multi-level Queue Scheduler
}
@Override
public void run() {
int count = 0; // A counter to track the number of processes
while(true){
synchronized(this){
Scheduler.fillQueue(Buffer); // Take contents in Buffer and put them in a separate queue in the scheduler
Scheduler.start(); // Start Scheduling algorithm
count++;
}
if(count >= 200) // If counter exceeds the maximum number of processes thread must yeild
yield();
notify(); // Notify Producer thread when buffer is empty
}
}
public void setReadyQueue(ReadyQueue q){
Buffer = q;
}
}
提前感谢您。您的代码的一个问题是,它在多线程生产者/消费者模型中存在一个常见错误。在调用
wait()
时,必须使用。例如:
try {
// we must do this test in a while loop because of consumer race conditions
while(!Buffer.isEmpty()) {
wait(); // When Buffer is empty wait until getting notification
...
}
} catch (InterruptedException e) {
e.printStackTrace();
}
问题是,如果您有多个正在消费的线程,您可能会通知一个线程,但随后另一个线程通过并将刚刚添加的项目出列。当一个线程在收到通知后从等待队列移动到运行队列时,它通常会被放在队列的末尾,可能在等待同步的其他线程后面
有关这方面的更多详细信息,请参阅我的。谢谢您的回复。您能更具体地说明是哪个线程导致了这个错误吗?消费者还是生产者?或者告诉我如何解决这个问题,因为我是线程新手。另外,notify
方法需要在synchronized
块中。错误在消费者while(true)
loop@Samantha中。我在回答中提供的链接包含了所有细节。无论何时,当您处于与消费者类似的条件下时,都必须再次测试您正在等待的条件。我阅读了您的文档,并试图通过包含可重入锁并使用锁技术来提供同步来修改代码,但是我在消费者线程中的wait()语句中得到了一个线程异常,该语句表示:java.lang.illegalMonitorStateException您需要对正在调用的对象进行wait()
或notify()
同步。你需要读一些文件,萨曼莎。我无法帮助您使用SO注释。