Java中Semaphore的图书馆员资源分配问题
请帮我解决这个由两部分组成的问题.这是第一部分:
我正在尝试用Java实现Librarian问题.维基百科上的Semaphore page给出了图书馆对信号量的类比.在第一部分中,我试图模拟这个问题.在我的情况下,我使用[主题专家]而不是房间作为资源.
我在实施中遇到的问题是关于学生与主题专家的关联.您将如何在以下secnario中执行此操作? SubjectMatterExpert需要做的就是打印学生ID(现在).
这是修改(编辑)的学生班级: 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 } } 这是修改(编辑)的Simulator类: 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; } } 解决方法
在您描述的原始图书管理员问题中,问题并不关心哪个学生在哪个房间,因此使用简单的线程安全计数器(即信号量)来实现对资源的控制.根据对问题的描述,仍然需要更改您的实现.一种方法是在图书管理员类上使用2种方法,一种用于请求SME,另一种用于返回它.
class Librarian { Semaphore sme = new Semaphore(NUMBER_OF_SMES); void requestSme() throws InterruptedException { sme.acquire(); } void releaseSme() { sme.release(); } } class Student { Librarian librarian; public void run() { libarian.requestSme(); try { // Do something finally { librarian.releaseSme(); } } } 但是,如果您确实需要知道哪个学生正在使用哪个SME,那么您需要一个不同的构造来管理资源,信号量已不再足够.一个例子可能是队列. class Librarian { BlockingQueue<SubjectMatterExpert> q = new ArrayBlockingQueue<SubjectMatterExpert>(NUMBER_OF_SMES); public Librarian() { for (int i = 0; i < NUMBER_OF_SMES; i++) q.put(new SubjectMatterExpert(String.valueOf(i)); } SubjectMatterExport requestSme() throws InterruptedException { q.take(); } void releaseSme(SubjectMatterExpert toRelease) { q.put(toRelease); } } class Student { Librarian librarian; public void run() { SubjectMatterExpert sme = libarian.requestSme(); try { System.out.println("Student: " + this + ",SME: " sme); finally { if (sme != null) librarian.releaseSme(sme); } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |