我有这节课

private static Stack<Integer> integers = new Stack<Integer>();

private static int nextInt()
{
    if(integers.isEmpty())
    {
        refill();
    }

    return integers.pop();
}

public static int peekInt()
{
    if(integers.isEmpty())
    {
        refill();
    }

    return integers.peek();
}

private static synchronized void refill()
{
    for(int i = 0; i<7; i++)
        integers.add(i);
    Collections.shuffle(integers);
}


和两个不同的线程调用方法nextInt和peekInt,但是有时它们会得到堆栈为空的异常,但是如果它们都在获取值之前都调用了refill,为什么会发生这种情况呢?

这是异常跟踪

Exception in thread "Thread-7" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:102)
at Utility.peekInt(Utility.java:26)
at Frame$repainter.run(Frame.java:72)
at java.lang.Thread.run(Thread.java:722)

最佳答案

您的代码不是线程安全的。考虑以下情形:堆栈仅包含一个元素/整数,并且在nextInt()和peekInt()方法中执行两个线程,这两个线程都将看到堆栈为非空,因此不调用refill()方法。线程在其他线程调用peek()之前稍微执行pop(),您将获得StackEmptyException。

同步nextInt()和peekInt()将解决此问题。

07-24 09:37
查看更多