为什么我的notify()不唤醒等待的线程? [英] why does my notify() not wake a waiting thread?

查看:322
本文介绍了为什么我的notify()不唤醒等待的线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的多线程算法,旨在在后台线程中加载一系列文件,并且让JPanel在加载完成后立即显示第一个图像.在JPanel的构造函数中,我启动加载程序,然后等待图像列表,如下所示:

I have a simple multithreaded algorithm designed to load a series of files in a background thread, and have a JPanel display the first image as soon as it is done loading. In the constructor of the JPanel, I start the loader, then wait on the list of images, as follows:

//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线程看起来像这样:

my Loader thread looks like this:

//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).我还验证了images对象实际上与正在等待的对象是同一对象.我尝试添加yield(),但这没有帮助.为什么对notifyAll()的调用不能立即唤醒等待的线程?

I have verified that execution passes through notifyAll() several times (usually >20) before the calling thread wakes up and displays the image in the frame. I have also verified that the images object is in fact the same object as the one being waited on. I have attempted adding a yield(), but that did not help. why does the call to notifyAll() not wake the waiting thread immediately?

推荐答案

我已经验证了调用线程被唤醒并在帧中显示图像之前,执行多次通过notifyAll()(通常> 20).

I have verified that execution passes through notifyAll() several times (usually >20) before the calling thread wakes up and displays the image in the frame.

您的加载器线程正在循环运行,立即caller.images上重新获取监视器,可能是在它放弃其时间片之前.

Your loader thread is looping, immediately reacquiring the monitor on caller.images, probably before it gives up its timeslice.

等待的线程必须先获取监视器,然后监视器才能取得进度-之所以不能这样做,是因为加载程序再次抓住了它.

The waiting thread has to reacquire the monitor before it can make progress - which it can't do because the loader has grabbed it again.

目前尚不清楚您要在这里实现什么,但是启动一个新线程,然后在构造函数中等待 通常是一个非常糟糕的主意.哎呀,如果在加载第一个图像之前根本无法做任何事情,为什么不同步进行呢?那就是你有效地所要做的...

It's not really clear what you're trying to achieve here, but starting a new thread and then waiting within a constructor is generally a really bad idea. Heck, if you can't do anything at all until the first image has loaded, why not do that synchronously? That's what you're effectively doing anyway...

这篇关于为什么我的notify()不唤醒等待的线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆