我有一个简单的多线程算法,旨在在后台线程中加载一系列文件,并让 JPanel 在加载完成后立即显示第一张图像。在 JPanel 的构造函数中,我启动加载器,然后在图像列表上等待,如下所示:
//MyPanel.java
public ArrayList<BufferedImage> images = new ArrayList<BufferedImage>();
int frame;
public MyPanel(String dir){
Thread loader = new thread (new Loader(dir, this));
loader.start();
frame = 0;
//miscellaneous stuff
synchronized(images){
while (images.isEmpty()){
images.wait();
}
}
this.setPrefferedSize(new Dimension(800,800));
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g)
g.drawImage(images.get(frame), 0, 0, 800, 800, null);
}
我的加载程序线程如下所示:
//Loader.java
String dir;
MyPanel caller;
public Loader(String dir, MyPanel caller){
this.dir = dir;
this.caller = caller;
}
@Override
public void run(){
File dirFile = new File(dir);
File[] files = dirFile.listFiles();
Arrays.sort(files);
for (File f : files) {
try {
synchronized (caller.images) {
BufferedImage buffImage = ImageIO.read(f);
caller.images.add(buffImage);
caller.images.notifyAll();
}
} catch (IOException e) {
}
}
}
我已经验证notifyAll()
在调用线程唤醒并在框架中显示图像之前执行多次(通常> 20)。我还验证了图像对象实际上与正在等待的对象是同一个对象。我尝试添加一个yield()
,但这没有帮助。为什么调用notifyAll()
不立即唤醒等待线程?