我有一个thread子类,它代表公共办公室的到达,还有一个thread子类,它代表案例工作者。
每次有人到达时,都会输入此人的姓名。办公室有两个入口,客人可以在这里输入姓名。候车室不能超过10人。如果还有更多,他们必须等到有空位。
办案人员点名。有两名办案人员。当然,只有输入了名称并且按输入顺序(如队列)调用时,才能调用名称。当所有的人都被叫来时,办案人员必须等到更多的人来。
到达者和办案人员的线程每次睡眠时间都是随机的(从1秒到10秒)。
我还有一个公共类,它包含一个arraylist,其中有一个名称列表作为方法,还有一些用于调用名称和输入名称的方法。它还包含用于解决问题的append和take方法(java的monitor)。
以下是我目前的代码:
import java.util.Random;
public class ThreadClass_Arrivals extends Thread {
private CommonClass commonClass;
public int threadID;
public ThreadClass_Arrivals(CommonClass commonClass, int threadID) {
this.commonClass = commonClass;
this.threadID = threadID;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
// time interval before a name is entered - the thread sleep between 1-10 seconds every time
Random random = new Random();
int randomNumber = random.nextInt(10) + 1;
int numberInThousand = randomNumber * 1000;
try {
Thread.sleep(numberInThousand);
} catch (InterruptedException e) {
e.printStackTrace();
}
commonClass.enterName(commonClass.namesList().get(commonClass.nameEnteredIndex), this.threadID);
// java monitor
commonClass.append((char) commonClass.nameEnteredIndex);
}
}
}
import java.util.Random;
public class ThreadClass_Caseworkers extends Thread {
private CommonClass commonClass;
public int threadID;
public ThreadClass_Caseworkers(CommonClass commonClass, int threadID) {
this.commonClass = commonClass;
this.threadID = threadID;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
// Time interval before a name is called - The thread sleep between 1-10 seconds every time
Random random = new Random();
int randomNumber = random.nextInt(10) + 1;
int numberInThousand = randomNumber * 1000;
try {
Thread.sleep(numberInThousand);
} catch (InterruptedException e) {
e.printStackTrace();
}
// java monitor
commonClass.take((char) commonClass.nameEnteredIndex);
commonClass.callAName(this.threadID, commonClass.nameCalledIndex);
}
}
}
import java.util.ArrayList;
public class CommonClass {
// java monitor
int N = 10;
char[] buffer = new char[N];
int nextin, nextout, count;
public int nameEnteredIndex;
public int nameCalledIndex;
// names list with 20 names
public ArrayList<String> namesList() {
ArrayList<String> names = new ArrayList<>();
names.add("Hans");
names.add("Jens");
names.add("Rasmus");
names.add("Kasper");
names.add("Niels");
names.add("Torben");
names.add("Peter");
names.add("Michael");
names.add("Lars");
names.add("Anders");
names.add("Bo");
names.add("Klaus");
names.add("Ib");
names.add("Kevin");
names.add("Oscar");
names.add("Nicolaj");
names.add("Alexander");
names.add("Morten");
names.add("Carsten");
names.add("Jakob");
return names;
}
public synchronized void enterName(String name, int threadID) {
if (threadID == 0) {
System.out.println("Name-entered (entrance1): " + name);
} else if (threadID == 1) {
System.out.println("Name-entered (entrance2): " + name);
}
nameEnteredIndex++;
}
public synchronized void callAName(int threadID, int index) {
if (threadID == 0) {
System.out.println("Name called (caseworker1): " + namesList().get(index));
} else if (threadID == 1) {
System.out.println("Name called (caseworker2): " + namesList().get(index));
}
nameCalledIndex++;
}
// java monitor
public synchronized void append(char x) {
if (count == N) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
buffer[nextin] = x;
nextin = (nextin + 1) % N;
count++;
notifyAll();
}
// java monitor
public synchronized void take(char x) {
if (count == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
x = buffer[nextout];
nextout = (nextout + 1) % N;
count--;
notifyAll();
}
}
public class MainApp {
public static void main(String[] args) {
// commonclass
CommonClass commonClass = new CommonClass();
// Thread - arrivals
ThreadClass_Arrivals threadClass_arrival1 = new ThreadClass_Arrivals(commonClass, 0);
ThreadClass_Arrivals threadClass_arrival2 = new ThreadClass_Arrivals(commonClass, 1);
threadClass_arrival1.start();
threadClass_arrival2.start();
// Thread - caseworkers
ThreadClass_Caseworkers threadClass_caseworker1 = new ThreadClass_Caseworkers(commonClass, 0);
ThreadClass_Caseworkers threadClass_caseworker2 = new ThreadClass_Caseworkers(commonClass, 1);
threadClass_caseworker1.start();
threadClass_caseworker2.start();
}
}
问题是有些名称在输入之前被调用,我也得到了arrayoutofbounceexception,即使列表中有20个名称,并且有一个循环从2个线程子类的列表中检索20个名称。
任何帮助都将不胜感激!
2条答案
按热度按时间osh3o9ms1#
下面是一个使用ada编程的非常类似问题的解决方案。在这个解决方案中,生产者和消费者一直运行,直到主任务通知他们停止为止。以这种方式,客户的数量是由时间控制的,而不是简单的循环计数。每一个生产商都会在客户进入的门口为他们命名,这样我们就可以看到这两个生产商都在工作。每个职员在处理客户时识别每个客户。“等候室”被实现为一个由十个元素组成的同步队列。synchronized队列处理所有数据同步问题,包括队列已满时挂起生产者,队列为空时挂起办事员(使用者)。
ada在包中定义程序模块。每个包必须有一个规范,它定义了模块的公共和私有接口。包通常还有一个定义模块行为的主体。主过程创建生产者任务类型和使用者任务类型的示例,这些示例立即开始运行。然后,main延迟(休眠)80秒,并为每个任务调用stop条目。
包体为:
本程序的主要程序是:
最后,此程序的一次执行的输出是:
11dmarpk2#
您所问问题的细节很复杂,但我可以帮助您理解java的监视器(wait、notify、notifyall)是如何用于生产者/消费者问题的。
在这里的中心是一排需要完成的工作。此队列(或其他有序数据结构)需要有两个同步方法:pop作业和push作业