现在我该如何处理在入口等待呢?我似乎无法找到一种方法来检查线程池是否“满”或类似的东西。
Hrm。有很多方法可以使用Java并发类来做到这一点。其中一种方法是将BlockingQueue
限制为2000的大小,代表停车位插槽。然后有4个单线程执行程序 - 服务线程池,每个线程池都有一个代表4个入口的50个队列。一旦第51辆车试图在入口排队,RejectedExecutionException
被抛出。
喜欢的东西:
final int NUM_SPACES_IN_LOT = 2000;
final int ENTRANCE_QUEUE_SIZE = 50;
final BlockingQueue<Car> parkingLot = new LinkedBlockingQueue<>(NUM_SPACES_IN_LOT);
...
ExecutorService entrance1 = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(ENTRANCE_QUEUE_SIZE));
ExecutorService entrance1 = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(ENTRANCE_QUEUE_SIZE));
ExecutorService entrance1 = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(ENTRANCE_QUEUE_SIZE));
ExecutorService entrance1 = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(ENTRANCE_QUEUE_SIZE));
...
private class ParkCar implements Runnable {
private final Car car;
public ParkCar(Car car) {
this.car = car;
}
public run() {
parkingLot.put(car);
}
}
...
Car car = new Car();
try {
entrance1.submit(new ParkCar(car));
} catch (RejectedExecutionException jee) {
// entrance is full
}
...
// remove a car from the lot, warning this is O(N)
parkingLot.remove(car);
你需要每一个入口队列,每个入口线程做并行停车。如果您不希望它引发异常,则可以调用entranceX.setRejectedExecutionHandler(...)
来设置处理程序,如果入口已满。
我不喜欢这个实现的东西是parkingLot.remove(...)
是O(N)
但是没有一个没有自己编写它的阻塞集。
您是否必须为此场景使用线程?如果没有看看队列。 https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html –
是的,线程和线程池都是必需的。正如我所看到的,即使我在入口处使用了队列,他们仍然会提交给执行者并建立另一个队列。 – svennebanan
有一个ThreadPoolExecutor构造函数,它接受一个BlockingQueue和一个RejectedExecutionHandler。这看起来很有希望解决这个不错的挑战。我想你必须做一些额外的编码来代表4个入口。 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html#ThreadPoolExecutor(int,%20int,%20long,%20java.util.concurrent.TimeUnit,%20java。 util.concurrent.BlockingQueue,%20java.util.concurrent.ThreadFactory,%20java.util.concurrent.RejectedExecutionHandler) –