Java 主线程因阻塞队列而挂起';s消费者(我以为是在另一个线程上)

Java 主线程因阻塞队列而挂起';s消费者(我以为是在另一个线程上),java,multithreading,blockingqueue,Java,Multithreading,Blockingqueue,我有一个阻塞测试(第一个代码块)。我有几个元素在一起工作。我有一个阻塞队列,我将事件放入其中,然后我有一个消费者将它们取下并发送到Amazon Kinesis。我很确定我的测试被阻塞了,因为队列阻塞了我的消费者,即使我认为它是在一个单独的线程上运行的 // Test.java @Test public void testWhileLoop() throws InterruptedException { ArrayBlockingQueue<Event> testQ = new

我有一个阻塞测试(第一个代码块)。我有几个元素在一起工作。我有一个阻塞队列,我将事件放入其中,然后我有一个消费者将它们取下并发送到Amazon Kinesis。我很确定我的测试被阻塞了,因为队列阻塞了我的消费者,即使我认为它是在一个单独的线程上运行的

// Test.java
@Test
public void testWhileLoop() throws InterruptedException {
    ArrayBlockingQueue<Event> testQ = new ArrayBlockingQueue<Event>(1024);
    // mockKinesis is a mock at the class level.
    KPLPoster kpl = new KPLPoster("TestStream", mockKinesis, testQ);
    Event event = new Event("TestMessage", "TestPartition");
    ListenableFuture<UserRecordResult> fakeReturn = Mockito.mock(ListenableFuture.class);

    final AtomicInteger numberOfWhileLoops = new AtomicInteger();

    Mockito.doAnswer(invocation -> {
        numberOfWhileLoops.incrementAndGet();
        return fakeReturn;
    })
    .when(mockKinesis)
    .addUserRecord("TestStream", "TestPartition", ByteBuffer.wrap("TestMessage".getBytes()));

    kpl.run(); // Hangs here

    for(int i = 100; i > 0; i--){
        testQ.put(event);
    }

    kpl.stop();
    kpl = null;

    assert(numberOfWhileLoops.toString()).equals("100");
}
最后,这里是我的KPLPoster(它扩展了BaseKinesisPoster)的相关
runOnce()
方法的一部分

// KPLPoster.java
@Override
protected void runOnce() throws Exception {
    Event event = inputQueue.take();
    //other stuff in my method
}
如何确保队列使用者上的阻塞不会阻塞测试/主线程?

当您调用

Thread.run();
Thread.start();
它调用被调用的方法。没有发生任何特殊情况,该方法在当前线程中运行

当你打电话的时候

Thread.run();
Thread.start();
这将启动线程,该线程反过来在新线程中调用run()

顺便说一句,在Java8中,Thread.stop()将抛出一个
UnsupportedOperationException
。你不应该用它。你应该让它自然结束。

当你打电话时

Thread.run();
Thread.start();
它调用被调用的方法。没有发生任何特殊情况,该方法在当前线程中运行

当你打电话的时候

Thread.run();
Thread.start();
这将启动线程,该线程反过来在新线程中调用run()


顺便说一句,在Java8中,Thread.stop()将抛出一个
UnsupportedOperationException
。你不应该用它。您应该让它自然完成。

我没有在线程上使用
Thread.stop()
,这是我自己完成的实现。它基本上会变成
shutdown=true
,因此它跳出while循环。不过谢谢你的指针。我强烈建议不要重写标准方法,也不要重写像线程这样的标准类。我不会重写。stop方法位于线程内的类上,而不是线程本身。这样很好,对吗?如果不是,那为什么会很糟糕?我完全理解不重写线程的stop方法本身。@bwighthunter您应该重写线程,因为这会导致混乱。我没有在线程上使用
Thread.stop()
,这是我自己完成的一个实现。它基本上会变成
shutdown=true
,因此它跳出while循环。不过谢谢你的指针。我强烈建议不要重写标准方法,也不要重写像线程这样的标准类。我不会重写。stop方法位于线程内的类上,而不是线程本身。这样很好,对吗?如果不是,那为什么会很糟糕?我完全理解不重写线程的stop方法本身。@bwighthunter您应该重写线程,因为这会导致混乱。将其用作Runnable的包装。我删除了我的答案,因为我遗漏了一些关键细节。我删除了我的答案,因为我遗漏了一些关键细节。