Java中的资源分配器

时间:2011-11-30 17:41:24

标签: java multithreading semaphore

我有这个资源分配器类

public class ResourceAllocator {

ArrayList<Request> queue = new ArrayList<>();
Lock lock = new ReentrantLock();
int maxResources;
int available;

public ResourceAllocator(int max) {
    maxResources = max;
    available = max;
}

public int getMax() {
    return maxResources;
}

public void getResources(Request req) {
    lock.lock();
    try {
        if (req.getRequest() <= available) {
            available = available - req.getRequest();
            req.allocate();
        } else {
            queue.add(req);
        }
    } finally {
        lock.unlock();
    }
}

public void returnResources(int n) {
    lock.lock();
    try {
        available = available + n;
        if (queue.size() > 0) {
            Request req = queue.get(0);
            while (queue.size() > 0 && 
                    req.getRequest() <= available) {
                available = available - req.getRequest();
                req.allocate();
                queue.remove(0);
                if (queue.size() > 0) {
                    req = queue.get(0);
                }
            }
        }
    } finally {
        lock.unlock();
    }
}

public int size(){
    return queue.size();
}
}

从线程

调用
public class QThread extends Thread {

Semaphore sem = new Semaphore(0);
ResourceAllocator resources;
int number;

public QThread(ResourceAllocator rs, int n) {
    resources = rs;
    number = n;
}

public void run() {
    int items = (int) (Math.random() * resources.getMax()) + 1;
    Request req = new Request(sem, items);
    resources.getResources(req);
    try {
        sem.acquire();
    } catch (InterruptedException ex) {
    }
    System.out.printf("Thread %3d got %3d resources\n", number, items);
    try{
        Thread.sleep(2000);
    }catch(InterruptedException ex){

    }
    resources.returnResources(items);
    System.out.printf("Thread %3d returned %3d resources\n", number,items);
}
}

除了资源分配FIFO之外,一切都很好。

任何想法如何更改此设置以允许具有小请求的客户端在具有大量请求的客户端之前继续超车?

3 个答案:

答案 0 :(得分:2)

如何使用优先级与请求大小相反的PriorityQueue?

答案 1 :(得分:2)

您可以使用最符合您需求的PriorityQueue,然后您可以实现自定义Comparator(如果您认为将来可能需要不同的排序实现),或者Comparable这将对您的Request进行排序,以便提交大小方面的作业,并先执行。

答案 2 :(得分:0)

如果您提前知道作业的大小,请使用PriorityQueue而不是ArrayList来保存作业并实施Comparable 生成你的Request对象,以便在大型作业之前对它们进行排序。