我有这节课
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()将解决此问题。