Java7技术系列:Queue

    xiaoxiao2023-10-06  173

    Java7技术系列:try-with-resource Java7技术系列:int与二进制的转换优化 Java7技术系列:MultiCatchException Java7技术系列:NIO.2异步IO Java7技术系列:DI依赖注入 Java7技术系列:Queue Java7技术系列:Java并发

    BlockingQueue 是Queue的简单扩展,它有两个特性:

    向队列中put()时,如果队列已满,它会让放入线程等待队列腾出空间。

    从队列中take()时,如果队列为空,它会导致取出线程阻塞。

    这两个特性非常有用,因为如果一个线程(或线程池)的能力超过了其他线程,比较快的线程就会被强制等待,可以对整个系统起到调节作用。

    BlockingQueue也提供了offer(E obj, int second, TimeUnit unit)增加对队列的控制力度,允许线程在遇到问题时可以与队列的交互中退出,但该方法不能有效解决“相连线程池问题”,可以通过TransferQueue解决。

    BlockingQueue的两个实现:

    LinkedBlockingQueue和ArrayBlockingQueue。它们的特性稍有不同:比如说,在已知队列的大小而能确定合适的边界时,用ArrayBlockingWueue非常高效,而LinkedBlockingQueue在某些情况下则会快一点儿。

    举例:兽医给宠物做检查(兽医就是消费者,宠物需要排队是生产者)

    public abstract class Pet { protected final String name; public Pet(String name) { this.name = name; } public abstract void examine(); } public class Cat extends Pet { public Cat(String name) { super(name); } public void examine() { System.out.println("Meow!"); } } public class Dog extends Pet { public Dog(String name) { super(name); } public void examine() { System.out.println("Woof!"); } } public class Appointment<T> { private final T toBeSeen; public T getPatient() { return toBeSeen; } public Appointment(T incoming) { toBeSeen = incoming; } } public class Veterinarian extends Thread { protected final BlockingQueue<Appointment<Pet>> appts; protected String text = ""; protected final int restTime; private boolean shutdown = false; public Veterinarian(BlockingQueue<Appointment<Pet>> lbq, int pause) { appts = lbq; restTime = pause; } public synchronized void shutdown() { shutdown = true } @Override public void run() { while (!shutdown) { seePatient(); try { Thread.sleep(restTime); } catch (InterruptedException e) { shutdown = true; } } } // 从队列中取出预约,并挨个检查对应的宠物,如果当前队列中没有预约等待,则会阻塞 public void seePatient() { try { Appointment<Pet> ap = appts.take(); Pet patient = ap.getPatient(); patient.examine(); } catch (InterruptedException e) { shutdown = true; } } } TransferQueue:

    TransferQueue 本质上是多了一项transfer()操作的BlockingQueue。如果接收线程处于等待状态,该操作会马上把工作项传给它,否则就会阻塞直到渠道工作项的线程出现。

    即正在处理工作项的线程在交付当前工作项之前不会开始其他工作项的处理工作。这样系统旧可以调控上游线程池获取新工作项的速度。

    TransferQueue能有效解决“相连线程池”引发的问题,比如上游的线程池比下游的快(也就是生产者的生产速度比消费者消费速度快,这容易导致LinkedBlockingQueue溢出;也有一种情况是消费者消费比生产者生产速度快,导致队列经常空着)

    提供了 tryTransfer(E obj, int second, TimeUnit unit),相当于BlockingQueue的offer()

    最新回复(0)