我有这个课程的一部分
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);
}
Run Code Online (Sandbox Code Playgroud)
两个不同的线程调用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)
Run Code Online (Sandbox Code Playgroud)
因为它不是线程安全的.假设堆栈中有一个元素,并且两个线程都在语句中if(integers.isEmpty()),它们都返回false并跳到下一个语句.现在,如果调用的线程nextInt()先进行调用integers.pop(),那么将从堆栈中取出一个元素,堆栈将为空.现在,当调用的另一个线程peekInt()执行时integers.peek(),它会抛出,EmptyStackException因为堆栈中没有元素.
你可以做的是尝试同步方法nextInt()和peekInt()旁边同步refill(),如下所示:
private static synchronized int nextInt(){...}
Run Code Online (Sandbox Code Playgroud)
public static synchronized int peekInt(){...}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
114 次 |
| 最近记录: |