一个简单的线程程序,其中一个写入器放入堆栈,一个读取器从堆栈中弹出。
java.util.Stack;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class MailBox
{
Stack<Integer> stack;
static int num;
public MailBox()
{
stack = new Stack<Integer>();
num = 1;
}
}
class Reader implements Runnable
{
MailBox box;
public Reader(MailBox box)
{
this.box = box;
}
public void run()
{
Thread.currentThread().setName("Reader " + MailBox.num++);
for(int i = 0; i < 5; ++i)
{
synchronized (box)
{
try {
box.wait();
if(!box.stack.empty() && !box.stack.isEmpty())
{
int data = box.stack.pop();
System.out.println(Thread.currentThread().getName() + " popped " + box.stack.pop());
}
else
{
System.out.println("Empty");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.currentThread();
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Writer implements Runnable
{
MailBox box;
public Writer(MailBox box)
{
this.box = box;
}
public void run()
{
int min = 1;
int max = 3;
Thread.currentThread().setName("Writer " + MailBox.num++);
for(int i = 0; i < 5; ++i)
{
synchronized(box)
{
int data = (int)Math.random() * max + min;
box.stack.push(data);
System.out.println(Thread.currentThread().getName() + " pushed " + data);
box.notifyAll();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class Review
{
public static void main(String args[])
{
MailBox box = new MailBox();
Writer writer = new Writer(box);
Writer apprentice = new Writer(box);
Writer publisher = new Writer(box);
Reader reader = new Reader(box);
Reader busy_reader = new Reader(box);
Reader slow_reader = new Reader(box);
Reader fast_reader = new Reader(box);
Reader ugly_reader = new Reader(box);
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(writer);
executor.execute(apprentice);
executor.execute(publisher);
executor.execute(reader);
executor.execute(busy_reader);
executor.execute(slow_reader);
executor.execute(fast_reader);
executor.execute(ugly_reader);
executor.shutdown();
}
}
程序似乎工作正常,但读者偶尔会弹出一个生成StackEmptyExceptions的空堆栈。
我有针对此的保护,为什么会产生这些例外?
答案 0 :(得分:1)
您正在弹出对象两次:
int data = box.stack.pop();
System.out.println(Thread.currentThread().getName() + " popped " + box.stack.pop());
正如您在documentation of stack中看到的,pop获取并删除数据。