この 2 部構成の質問について教えてください。最初の部分は次のとおりです。
(パート 2: コードを更新しました - 要件が少し変更されました。)
Java でライブラリアンの問題を実装しようとしています。ウィキペディアのセマフォのページでは、セマフォのライブラリのアナロジーが提供されています。最初の部分では、この問題をモデル化しようとしています。私の場合、ルームの代わりに [対象分野の専門家] をリソースとして使用しています。
図書館に 10 室の同一の自習室があり、一度に 1 人の学生が使用することを想定しているとします。学生が自習室を利用したい場合は、紛争を防ぐためにフロントカウンターから部屋をリクエストする必要があります。部屋の使用が終わったら、学生はカウンターに戻り、1 つの部屋が空いたことを示さなければなりません。空いている部屋がない場合、学生は誰かが部屋を放棄するまでカウンターで待ちます。
部屋は同一であるため、フロント デスクの司書はどの部屋が使用されているかを把握しておらず、空いている部屋の数のみを把握しています。学生が部屋をリクエストすると、司書はこの数を減らします。学生が部屋を解放すると、司書はこの数を増やします。部屋へのアクセスが許可されると、その部屋は必要な期間使用できるため、事前に部屋を予約することはできません。
私の実装で直面している問題は、学生と主題の専門家との関連付けに関するものです。次のシナリオでこれをどのように行いますか? SubjectMatterExpert
学生証を印刷するだけです(今のところ)。
パート 2: 新しい要件:
- 学生、SME、ブック クローゼットの固定数があります
- 学生は最初に特定の数の本を持っています (現在、本は単なる数字です)
- SME はブック クローゼットから本を追加またはチェックアウトします。生徒のリクエスト
- 生徒は追加またはチェックアウト アクション、本の数、ブック クローゼットを指定します
これは変更 (編集) された Student クラスです。
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();
}
}
}
これは、修正 (編集) された Subject Matter Expert クラスです。
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;
}
}