2016-12-15 90 views
1

所以这是我想拿出一个解决方案的情景:检查一个线程池是否有等待执行的任务?

你违章停车的房子2000免费插槽。它有4个入口。当停车场已满时,每个入口处只允许等待50辆汽车。

我最终做的是用2000个线程创建一个线程池,然后用4个线程表示入口。随机间隔,他们创建汽车Tasks(他们基本上只是调用Thread.sleep())并将它们提交给线程池。

当线程池忙于执行2000个任务时,问题就出现了,新提交的任务被放入队列中等待执行。我如何处理在入口处等待?我似乎无法找到一种方法来检查线程池是否“完整”或类似的东西。或者,也许我的做法是完全错误的。

+0

您是否必须为此场景使用线程?如果没有看看队列。 https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html –

+0

是的,线程和线程池都是必需的。正如我所看到的,即使我在入口处使用了队列,他们仍然会提交给执行者并建立另一个队列。 – svennebanan

+0

有一个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) –

回答

0

现在我该如何处理在入口等待呢?我似乎无法找到一种方法来检查线程池是否“满”或类似的东西。

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)但是没有一个没有自己编写它的阻塞集。

相关问题