处理ThreadPoolExecutor中的条件以执行

时间:2016-08-02 16:49:00

标签: java multithreading threadpoolexecutor

我有以下情景 大楼里有一个洗手间 它将有2种类型[截至目前]的厕所。 MALEFEMALE,其数量为n。

如果一群人进入洗手间。我希望他们尽可能占用最多的房间。

假设有20人一次进入洗手间,使用以下组合

People  20
Male 10 Female 10

RestRoom Avaialbiltiy
MALE 2
FEMALE 1

有些人会花更多的时间,所以下一个人必须排队等候。male无法进入female厕所,反之亦然。

对于上述情况,我已经扩展了ThreadpoolExecutor并逐个添加Person,并且只要匹配的厕所是可用的,请立即分配。

所以这是示例的MCVE。我想检查这是否是在ThreadPool中处理条件的正确方法

RestRoom.java

import java.util.HashMap;
import java.util.Map;

public enum RestRoom {

    MALE,
    FEMALE;//will extend for ex [Differently Abled]

    public int maxInstance = 0;

    public RestRoom withMaxInstance(int maxInstance) {
        this.maxInstance = maxInstance;
        return this;
    }

    public static int getTotalNoOfRestRooms() {
        int count = 0;
        for (RestRoom room : RestRoom.values()) {
            count += room.maxInstance;
        }
        return count;
    }

    public static Map<RestRoom, Integer> getAvailabiltyAsMap() {
        Map<RestRoom, Integer> avaialbilty = new HashMap<>();
        for (RestRoom room : RestRoom.values()) {
            avaialbilty.put(room, room.maxInstance);
        }
        return avaialbilty;
    }
}

Person.java(Runnable)

import java.util.logging.Level;
import java.util.logging.Logger;

public class Person implements Runnable {

    private final String name;

    private final RestRoom gender;

    private int second;

    public Person(String name, RestRoom gender) {
        this.name = name;
        this.gender = gender;
    }

    public Person withTime(int second) {
        this.second = second;
        return this;
    }

    @Override
    public void run() {
        try {
            System.out.println("Running " + name + " with " + gender);
            Thread.sleep(second * 1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Person.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public String getName() {
        return name;
    }

    public RestRoom getGender() {
        return gender;
    }

    @Override
    public String toString() {
        return "Person{" + "name=" + name + ", gender=" + gender + '}';
    }

}

CustomThreadPool.java

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class CustomThreadPool extends ThreadPoolExecutor {

    Map<RestRoom, Integer> avaialbilty = new HashMap<>();
    LinkedBlockingDeque<Runnable> remaining = new LinkedBlockingDeque<>();

    public CustomThreadPool(int corePoolSize, long keepAliveTime) {
        super(corePoolSize, corePoolSize, keepAliveTime, TimeUnit.MINUTES, new LinkedBlockingDeque<Runnable>());
        avaialbilty = RestRoom.getAvailabiltyAsMap();
    }

    @Override
    protected void afterExecute(Runnable runnable, Throwable throwable) {
        avaialbilty.put(getRestRoomFor(runnable), avaialbilty.get(getRestRoomFor(runnable)) + 1);
        for (int i = 0; i < remaining.size(); i++) {
            execute(remaining.remove());
        }
        if (remaining.isEmpty()) {
            shutdown();
        }
    }

    @Override
    public void execute(Runnable runnable) {
        if (avaialbilty.get(getRestRoomFor(runnable)) > 0) {
            avaialbilty.put(getRestRoomFor(runnable), avaialbilty.get(getRestRoomFor(runnable)) - 1);
            super.execute(runnable);
        } else {
            remaining.add(runnable);
        }
    }

    private RestRoom getRestRoomFor(Runnable runnable) {
        return asPerson(runnable).getGender();
    }

    private Person asPerson(Runnable runnable) {
        return (Person) runnable;
    }

}

Test.java

public class Test {

    public static void main(String[] args) {
        RestRoom.MALE.withMaxInstance(3);
        RestRoom.FEMALE.withMaxInstance(2);
        CustomThreadPool threadPool = new CustomThreadPool(RestRoom.getTotalNoOfRestRooms(), 2);
        for (int i = 0; i < 10; i++) {
            threadPool.execute(new Person("M" + i, RestRoom.MALE).withTime(2));
            threadPool.execute(new Person("F" + i, RestRoom.FEMALE).withTime(1));
        }
    }
}

0 个答案:

没有答案