Librarian resource allocation in semaphore in Java

Please help me solve this two - Part problem This is the first part:

I'm trying to implement the libraian problem in Java The semaphore page on Wikipedia gives the library's analogy to semaphores In the first part, I try to simulate this problem In my case, I use [subject matter experts] instead of rooms as resources

The problem I encountered in the implementation is about the relationship between students and subject experts How would you do this in secnario below? What subject matter expert needs to do is print the student ID (now)

This is the revised (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 revised (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();
    }
}

This is the (New) book close 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;
    }
}

Solution

In the original librarian problem you described, the problem does not care which student is in which room, so a simple thread safe counter (i.e. semaphore) is used to control resources According to the description of the problem, you still need to change your implementation One method is to use two methods on the librarian class, one for requesting SME and the other for returning it

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();
         }
     }
}

However, if you really need to know which student is using which SME, you need a different construct to manage resources, and the semaphore is no longer sufficient An example might be a queue

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);
         }
     }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>