java - StackEmptyException 意外发生

标签 java stack

我有这部分类(class)

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)

最佳答案

因为它不是线程安全的。假设堆栈中有一个元素,并且两个线程都位于语句 if(integers.isEmpty()) 处,这两个线程都将返回 false 并跳至下一条语句。现在,如果调用 nextInt() 的线程首先调用 integers.pop(),那么将从堆栈中取出一个元素,并且堆栈将为空。现在,当调用 peekInt() 的另一个线程执行 integers.peek() 时,它将抛出 EmptyStackException,因为堆栈中没有元素.

除了同步 refill() 之外,您还可以尝试同步方法 nextInt()peekInt(),如下所示:

private static synchronized int nextInt(){...}
public static synchronized int peekInt(){...}

关于java - StackEmptyException 意外发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16126250/

相关文章:

java - 提示如何从 List<string> 中提取文本

java - 结构设计模式

c - 为什么使用两个堆栈的队列不起作用?

pointers - 为什么指向堆栈中地址的 ESP 每次跳转 4h?

c - 如何破坏 C 程序中的堆栈

Java 在 JPanel 中限制 fps

java - HTTP 404 应该在 HTTP 403 状态代码之前吗?

java - 为什么 Jersey 不尊重动态绑定(bind)过滤器中的优先级?

c - 如何在 C 中显示堆栈的内容?

c - 使用数组和堆栈进行十进制到二进制转换