如何让BlockingQueue接受多种类型?

时间:2015-05-12 08:05:01

标签: java generics blockingqueue

我有课程X,课程Y和课程Z。如果XY执行特定条件,则应将其放入BlockingQueue。类Z只是从队列中获取它们。

我知道创造这样的东西:

BlockingQueue<X,Y> BQueue=new ArrayBlockingQueue<X,Y>(length);

是非法的。如何正确使用?

2 个答案:

答案 0 :(得分:2)

您可以执行Sasha建议并使用BlockingQueue<Object>但我更喜欢在界面中声明常用功能,然后让每个类处理它自己的功能而不是使用instanceof声明:

public interface Common {

    boolean shouldEnqueue();

    void doSomething();

}

public class X implements Common {

    public boolean shouldEnqueue() {
        ...
    }

    public void doSomething() {
        System.out.println("This is X");
    }
}

public class Y implements Common {

    public boolean shouldEnqueue() {
        ...
    }

    public void doSomething() {
        System.out.println("This is Y");
    }
}

public class Producer {

    private final BlockingQueue<Common> queue;

    void maybeEnqueue(Common c) {
        if(c.shouldEnqueue()) {
            queue.add(c);
        }
    }
}

public class Consumer {
    private final BlockingQueue<Common> queue;

    void doSomething() {
        queue.take().doSomething();
    }
}

答案 1 :(得分:0)

最简单的方法是允许BlockingQueue接受任何对象类型:

BlockingQueue<Object> q = new ArrayBlockingQueue<>(length);

然后,在take()操作中,您只需查看该对象的特定类:

Object o = q.take();
if (o instanceof X) {
    X x = (X) o;
    // do work with x
} else if (o instanceof Y) {
    Y y = (Y) o;
    // do work with y
} else {
    // o is neither X nor Y
}

如果XY从公共类继承或实现公共接口,请使您的队列更具体:

BlockingQueue<XYInterface> q = new ArrayBlockingQueue<>(length);