加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java中Semaphore的图书馆员资源分配问题

发布时间:2020-12-15 02:24:31 所属栏目:Java 来源:网络整理
导读:请帮我解决这个由两部分组成的问题.这是第一部分: (Part 2: I have updated the code since – requirements have changed a bit.) 我正在尝试用Java实现Librarian问题.维基百科上的Semaphore page给出了图书馆对信号量的类比.在第一部分中,我试图模拟这个
请帮我解决这个由两部分组成的问题.这是第一部分:

(Part 2: I have updated the code since – requirements have changed a
bit.)

我正在尝试用Java实现Librarian问题.维基百科上的Semaphore page给出了图书馆对信号量的类比.在第一部分中,我试图模拟这个问题.在我的情况下,我使用[主题专家]而不是房间作为资源.

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.

我在实施中遇到的问题是关于学生与主题专家的关联.您将如何在以下secnario中执行此操作? SubjectMatterExpert需要做的就是打印学生ID(现在).

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

这是修改(编辑)的学生班级:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读