Java线程连接问题

发布于 2024-11-28 16:53:12 字数 3573 浏览 0 评论 0原文

public void setGifImage(InputStream inputStream) {
        checkWidget();
        if (thread != null) {
            thread.stopRunning();
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        ImageLoader loader = new ImageLoader();

        try {
            loader.load(inputStream);
        } catch (Exception e) {
            this.image = null;
            return;
        }

        if (loader.data[0] != null){
            System.out.println("set to new picture");
            this.image = new Image(this.getDisplay(), loader.data[0]);
        }

        if (loader.data.length > 1) {
            System.out.println("start animation");
            thread = new GifThread(loader);
            thread.start();
        }else{
            System.out.println("paint static picture");
        }

        redraw();
    }

线程 :

private class GifThread extends Thread {

        private int imageNumber = 0;
        private ImageLoader loader = null;
        private boolean run = true;

        public GifThread(ImageLoader loader) {
            this.loader = loader;
        }

        public void run() {
            while (run) {
                int delayTime = loader.data[imageNumber].delayTime;
                try {
                    Thread.sleep(delayTime * 10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (!GifCLabel.this.isDisposed()) {
                    // if a asynchronous thread is running, this new runnable will be queued
                    GifCLabel.this.getDisplay().asyncExec(new Runnable() {
                        public void run() {
                            if (!GifCLabel.this.isDisposed()) {
                                imageNumber = imageNumber == loader.data.length - 1 ? 0 : imageNumber + 1;
                                if (!GifCLabel.this.image.isDisposed())
                                    GifCLabel.this.image.dispose();
                                ImageData nextFrameData = loader.data[imageNumber];
                                System.out.println("set to frame " + imageNumber);
                                GifCLabel.this.image = new Image(GifCLabel.this.getDisplay(), nextFrameData);
                                GifCLabel.this.redraw();
                            } else
                                stopRunning();
                        }
                    });
                } else
                    stopRunning();
            }
        }

        public void stopRunning() {
            run = false;
        }
    }

输出 :

2011-08-10 03:44:24 DEBUG  - 日志服务Ready!
2011-08-10 03:44:28 DEBUG  - current is null
2011-08-10 03:44:28 DEBUG  - found : amarsoft.dbmp.function.ui.FunctionListPage@1079ff
2011-08-10 03:44:28 DEBUG  - can go back ? false
2011-08-10 03:44:28 DEBUG  - can go forward ? false
set to new picture
start animation
2011-08-10 03:44:28 DEBUG  - 尝试连接至 - jdbc:mysql://localhost:3306/credit 驱动配置:MySQL 驱动类:com.mysql.jdbc.Driver@1f7abae 连接属性:{user=root, password=root}
set to frame 1
set to frame 2
set to frame 3
set to frame 4
[amarsoft.dbmp.function.ui.FunctionListPage$1@29f93b, amarsoft.dbmp.function.ui.FunctionView$1@1a998c7]
set to new picture
paint static picture
set to frame 5

我想知道为什么线程在 thread.join() 之后仍然运行?据我所知, thread.join() 等待线程死亡,但你可以看到输出中的最后一行,线程在死亡后运行......

public void setGifImage(InputStream inputStream) {
        checkWidget();
        if (thread != null) {
            thread.stopRunning();
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        ImageLoader loader = new ImageLoader();

        try {
            loader.load(inputStream);
        } catch (Exception e) {
            this.image = null;
            return;
        }

        if (loader.data[0] != null){
            System.out.println("set to new picture");
            this.image = new Image(this.getDisplay(), loader.data[0]);
        }

        if (loader.data.length > 1) {
            System.out.println("start animation");
            thread = new GifThread(loader);
            thread.start();
        }else{
            System.out.println("paint static picture");
        }

        redraw();
    }

the thread :

private class GifThread extends Thread {

        private int imageNumber = 0;
        private ImageLoader loader = null;
        private boolean run = true;

        public GifThread(ImageLoader loader) {
            this.loader = loader;
        }

        public void run() {
            while (run) {
                int delayTime = loader.data[imageNumber].delayTime;
                try {
                    Thread.sleep(delayTime * 10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (!GifCLabel.this.isDisposed()) {
                    // if a asynchronous thread is running, this new runnable will be queued
                    GifCLabel.this.getDisplay().asyncExec(new Runnable() {
                        public void run() {
                            if (!GifCLabel.this.isDisposed()) {
                                imageNumber = imageNumber == loader.data.length - 1 ? 0 : imageNumber + 1;
                                if (!GifCLabel.this.image.isDisposed())
                                    GifCLabel.this.image.dispose();
                                ImageData nextFrameData = loader.data[imageNumber];
                                System.out.println("set to frame " + imageNumber);
                                GifCLabel.this.image = new Image(GifCLabel.this.getDisplay(), nextFrameData);
                                GifCLabel.this.redraw();
                            } else
                                stopRunning();
                        }
                    });
                } else
                    stopRunning();
            }
        }

        public void stopRunning() {
            run = false;
        }
    }

the output :

2011-08-10 03:44:24 DEBUG  - 日志服务Ready!
2011-08-10 03:44:28 DEBUG  - current is null
2011-08-10 03:44:28 DEBUG  - found : amarsoft.dbmp.function.ui.FunctionListPage@1079ff
2011-08-10 03:44:28 DEBUG  - can go back ? false
2011-08-10 03:44:28 DEBUG  - can go forward ? false
set to new picture
start animation
2011-08-10 03:44:28 DEBUG  - 尝试连接至 - jdbc:mysql://localhost:3306/credit 驱动配置:MySQL 驱动类:com.mysql.jdbc.Driver@1f7abae 连接属性:{user=root, password=root}
set to frame 1
set to frame 2
set to frame 3
set to frame 4
[amarsoft.dbmp.function.ui.FunctionListPage$1@29f93b, amarsoft.dbmp.function.ui.FunctionView$1@1a998c7]
set to new picture
paint static picture
set to frame 5

I wonder why the thread still run after thread.join()? As I know, thread.join() wait thread to die,but you can see the last line in output, thread run after die...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苏佲洛 2024-12-05 16:53:12

这里的问题是,您线程调用 getDisplay().asyncExec() ,它基本上将事件发送到 UI 线程以执行打印 “设置为框架” 的 Runnable。

最好使用 syncExec() 并检查 Runnable 内的 run 变量状态。

另一个提示:

  1. 捕获 InterruptedException 而不执行任何操作并不是一个好主意。
  2. stopRunnable() 内调用 interrupt
  3. sleep 结束后检查 run 变量状态。

干杯,
最大限度

The issue here is that you thread calls getDisplay().asyncExec() which basically sends event to UI thread to execute the Runnable that prints "set to frame ".

Better to use syncExec() and check run variable status inside Runnable too.

Another hints:

  1. it's not a good idea to catch InterruptedException and do nothing.
  2. call interrupt inside stopRunnable()
  3. check run variable status after sleep ends.

Cheers,
Max

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文