Java中信号量的图书管理员资源分配问题
请帮我解决这个由两部分组成的问题。这是第一部分:
(第 2 部分:我已更新代码,因为 - 要求已更改 位。)
我正在尝试用 Java 实现 Librarian 问题。维基百科上的信号量页面给出了信号量的库类比。在第一部分中,我尝试对这个问题进行建模。就我而言,我使用[主题专家]而不是房间作为资源。
假设图书馆有 10 个相同的自习室,一次可供一名学生使用。为避免纠纷,学生如需使用自习室,必须向前台申请房间。当学生使用完一间房间后,学生必须返回柜台并表明一间房间已空闲。如果没有空房间,学生就在柜台等待,直到有人让出房间。
由于房间相同,前台图书管理员不记录哪个房间已被占用,只记录可用房间的数量。当学生请求房间时,图书馆员会减少这个数字。当学生释放房间时,图书管理员会增加该数字。一旦获得房间访问权限,该房间就可以根据需要使用,因此无法提前预订房间。
我在实施中面临的问题是关于学生与主题专家的关联。在下面的场景中你会如何做到这一点? SubjectMatterExpert
需要做的就是打印学生 ID(目前)。
第 2 部分:新要求:
- 学生、中小企业和书柜的数量是固定的
- 学生一开始就有一定数量的书籍(目前书籍只是数字)
- 中小企业应学生的要求从书柜添加或借出书籍
- 学生指定添加或签出操作、书籍数量和书柜
这是修改(编辑)的学生班级:
package librarysimulation;
public class Student extends Thread {
String studentId = "";
Librarian librarian = null;
int bookCount = 0;
public Student(String id, Librarian lib, int book) {
studentId = id;
librarian = lib;
bookCount = book;
}
@Override
public void run() {
System.out.println("Student " + studentId + " is requesting SME...");
librarian.requestSME();
try {
// Do something
System.out.println("Student " + studentId + " has access to an SME.");
//How do I ask the SME to add OR checkOut 'x' number of books
//from a given BookCloset?
} finally {
librarian.releaseSME();
}
}
}
这是修改(编辑)的图书管理员班级:
package librarysimulation;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Librarian {
public Semaphore sme;
public int bookClosetCount = 0;
public Librarian(int smeCount, int bookCloset) {
sme = new Semaphore(smeCount, true);
bookClosetCount = bookCloset;
//openLibrary(smeCount);
}
//Receive SME request from the Student here
public void requestSME() {
try {
sme.acquire();
//assign student to SME
} catch (InterruptedException ex) {
Logger.getLogger(Librarian.class.getName()).log(Level.SEVERE, null, ex);
}
}
//Release SME from the Student here
public void releaseSME() {
sme.release();//release SME
}
//Set the SME threads active (from constructor)
//i.e., when the library opens, have the SMEs ready
public final void openLibrary(int roomCount) {
for (int i = 0; i < roomCount; i++) {
SubjectMatterExpert s = new SubjectMatterExpert(String.valueOf(i));
s.start();
}
}
}
这是修改(编辑)的主题专家类:
package librarysimulation;
public class SubjectMatterExpert extends Thread {
String smeId = "";
SubjectMatterExpert(String id) {
smeId = id;
}
@Override
public void run(){
//Handle Student request
//Students specify if they are checking out books or returning books
//Students specify number of books
//Students specify which closet
//SME simply executes the method from the Book Closet instance
}
}
这是修改(编辑)的模拟器类:
package librarysimulation;
public class Simulator extends Thread {
public static final int STUDENT_COUNT = 50;
public static final int SME_COUNT = 3;
public static final int BOOKCLOSET_COUNT = 10;
public static final int BOOK_PER_STUDENT_COUNT = 10;
@Override
public void run() {
//Instantiate Library//New library with 3 SMEs
Librarian lib = new Librarian(SME_COUNT, BOOKCLOSET_COUNT);
//Create students
int i = 0;
while (i < STUDENT_COUNT) {
Student s = new Student(String.valueOf(i), lib, BOOK_PER_STUDENT_COUNT);
s.start();
i++;
}
}
public static void main(String[] args) {
Simulator s = new Simulator();
s.start();
}
}
这是(新的)Book Closet 类:
package librarysimulation;
public class BookCloset {
int closetId;
int bookCount = 0;
public BookCloset(int id, int book) {
closetId = id;
bookCount = book;
}
public int addBook(int book){
return bookCount + book;
}
public int checkOutBook(int book){
int finalBookCount = bookCount - book;
//Change book count iff it makes sense to do so
if(finalBookCount >= 0)
bookCount = finalBookCount;
//If return value is -ve, handle accordingly
return finalBookCount;
}
}
Please help me with this two-part question. Here is the first part:
(Part 2: I have updated the code since - requirements have changed a
bit.)
I am trying to implement the Librarian problem in Java. The Semaphore page on Wikipedia gives the library analogy of a Semaphore. In the first part, I am trying to model this problem. In my case, I am using a [Subject Matter Expert] instead of a Room as a resource.
Suppose a library has 10 identical study rooms, intended to be used by one student at a time. To prevent disputes, students must request a room from the front counter if they wish to make use of a study room. When a student has finished using a room, the student must return to the counter and indicate that one room has become free. If no rooms are free, students wait at the counter until someone relinquishes a room.
Since the rooms are identical, the librarian at the front desk does not keep track of which room is occupied, only the number of free rooms available. When a student requests a room, the librarian decreases this number. When a student releases a room, the librarian increases this number. Once access to a room is granted, the room can be used for as long as desired, and so it is not possible to book rooms ahead of time.
The problem I am facing in my implementation is regarding association of a Student with a Subject Matter Expert. How would you do this in the following secnario? All that the SubjectMatterExpert
needs to do is print the Student Id (for now).
Part 2: New requirements:
- There are fixed number of Students, SMEs, and Book Closets
- Students have certain number of Books at the beginning (presently, books are just numbers)
- SMEs add or check out books from the Boook Closet at a Student's request
- Students specify add or check out action, number of books, and the Book Closet
This is the modified (edited) Student class:
package librarysimulation;
public class Student extends Thread {
String studentId = "";
Librarian librarian = null;
int bookCount = 0;
public Student(String id, Librarian lib, int book) {
studentId = id;
librarian = lib;
bookCount = book;
}
@Override
public void run() {
System.out.println("Student " + studentId + " is requesting SME...");
librarian.requestSME();
try {
// Do something
System.out.println("Student " + studentId + " has access to an SME.");
//How do I ask the SME to add OR checkOut 'x' number of books
//from a given BookCloset?
} finally {
librarian.releaseSME();
}
}
}
This is the modified (edited) Librarian class:
package librarysimulation;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Librarian {
public Semaphore sme;
public int bookClosetCount = 0;
public Librarian(int smeCount, int bookCloset) {
sme = new Semaphore(smeCount, true);
bookClosetCount = bookCloset;
//openLibrary(smeCount);
}
//Receive SME request from the Student here
public void requestSME() {
try {
sme.acquire();
//assign student to SME
} catch (InterruptedException ex) {
Logger.getLogger(Librarian.class.getName()).log(Level.SEVERE, null, ex);
}
}
//Release SME from the Student here
public void releaseSME() {
sme.release();//release SME
}
//Set the SME threads active (from constructor)
//i.e., when the library opens, have the SMEs ready
public final void openLibrary(int roomCount) {
for (int i = 0; i < roomCount; i++) {
SubjectMatterExpert s = new SubjectMatterExpert(String.valueOf(i));
s.start();
}
}
}
This is the modified (edited) Subject Matter Expert class:
package librarysimulation;
public class SubjectMatterExpert extends Thread {
String smeId = "";
SubjectMatterExpert(String id) {
smeId = id;
}
@Override
public void run(){
//Handle Student request
//Students specify if they are checking out books or returning books
//Students specify number of books
//Students specify which closet
//SME simply executes the method from the Book Closet instance
}
}
This is the modified (edited) Simulator class:
package librarysimulation;
public class Simulator extends Thread {
public static final int STUDENT_COUNT = 50;
public static final int SME_COUNT = 3;
public static final int BOOKCLOSET_COUNT = 10;
public static final int BOOK_PER_STUDENT_COUNT = 10;
@Override
public void run() {
//Instantiate Library//New library with 3 SMEs
Librarian lib = new Librarian(SME_COUNT, BOOKCLOSET_COUNT);
//Create students
int i = 0;
while (i < STUDENT_COUNT) {
Student s = new Student(String.valueOf(i), lib, BOOK_PER_STUDENT_COUNT);
s.start();
i++;
}
}
public static void main(String[] args) {
Simulator s = new Simulator();
s.start();
}
}
an this is the (new) Book Closet class:
package librarysimulation;
public class BookCloset {
int closetId;
int bookCount = 0;
public BookCloset(int id, int book) {
closetId = id;
bookCount = book;
}
public int addBook(int book){
return bookCount + book;
}
public int checkOutBook(int book){
int finalBookCount = bookCount - book;
//Change book count iff it makes sense to do so
if(finalBookCount >= 0)
bookCount = finalBookCount;
//If return value is -ve, handle accordingly
return finalBookCount;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您描述的原始图书管理员问题中,问题并不关心哪个学生在哪个房间,因此使用一个简单的线程安全计数器(即信号量)来实现对资源的控制。根据问题的描述,仍然需要更改您的实现。一种方法是图书馆员类上的 2 个方法,一种用于请求 SME,另一种用于返回它。
但是,如果您确实需要知道哪个学生正在与哪个 SME 合作,那么您需要不同的构造来管理资源,信号量不再足够。队列就是一个例子。
In the original librarian problem you described, the problem doesn't care which student is in which room, therefore uses a simple thread safe counter (i.e. a Semaphore) to implement control of the resources. Following that description of the problem there still needs to be an alteration of your implementation. One approach is to 2 methods on the librarian class, one for requesting the SME, the other for returning it.
However if you do need to know which Student is working with which SME, then you need a different construct for managing the resources, a Semaphore is no longer sufficient. One example could be a Queue.
让 SME 作为线程在 while 循环中运行是有意义的。查看下面的一些起始代码。此外,您需要在模拟开始时初始化书柜。我不知道你正在采取的整个方法。
实施并与论坛中的其他人仔细检查。我是新来的。不过,更有经验的声音可能有更好的发言权。希望这最终能有所帮助(=不会造成伤害)。
It makes sense to have SMEs as threads running in a while loop. Check out some starting codes below. Also, you need to initialize the book closet somewhere at the beginning of the simulation. I don't know about the whole approach you are taking though.
Implement and double check with others in the forum. I am new here. More experienced voices may have a better say though. Hope this helps (= does not hurt) at the end.