Распределитель ресурсов в Java - PullRequest
1 голос
/ 30 ноября 2011

У меня есть этот класс распределителя ресурсов

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 ]

2 голосов
/ 30 ноября 2011

Вы можете использовать PriorityQueue, который лучше всего соответствует вашим потребностям, тогда вы можете реализовать пользовательский Comparator (если вы думаете, что в будущем вам может потребоваться другая реализация для сортировки), или же Comparable, который будет сортировать ваши Request так что задания по размеру представляются, выполняются первыми.

2 голосов
/ 30 ноября 2011

как насчет использования PriorityQueue, где приоритет является обратным к размеру запроса?

0 голосов
/ 30 ноября 2011

Если вы заранее знаете размер задания, используйте PriorityQueue вместо ArrayList для хранения заданий и реализации Comparable вашего объекта Request таким образом, что небольшие задания перед этим сортируются.большие.

...