微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – j2me网络,线程和死锁

简单的midlet代码(类Moo)下面(摘录后)死锁(至少我认为在线程 here上阅读这篇文章后死锁).

我转载了帖子的相关摘录:


String url = ...
    Connection conn = null;

    try {
        conn = Connector.open( url );
        // do something here
    }
    catch( IOException e ){
        // error
    }

问题的根源是open()调用的阻塞性质.在某些平台上,系统在封面下进行实际连接,相当于单独的线程.调用线程阻塞,直到连接线程建立连接.同时,安全子系统可能要求用户确认连接,并且连接线程阻塞直到事件线程得到用户的确认.发生死锁是因为事件线程已在等待连接线程.


public class Moo extends MIDlet {

    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
        // Todo Auto-generated method stub

    }

    protected void pauseApp() {
    }

    protected void startApp() throws MIDletStateChangeException {
        display display = display.getdisplay(this);
        MyCanvas myCanvas = new MyCanvas();
        display.setCurrent(myCanvas);
        myCanvas.repaint();

    }

    class MyCanvas extends Canvas {

        protected void paint(Graphics graphics) {
                try {
                        Image bgImage = Image.createImage(getWidth(),getHeight());

                        httpconnection httpconnection = (httpconnection) Connector
                                        .open("https://stackoverflow.com/content/img/so/logo.png");
                        Image image = Image.createImage(httpconnection
                                        .openInputStream());
                        bgImage.getGraphics().drawImage(image,0);
                        httpconnection.close();

                        graphics.drawImage(bgImage,0);
                } catch (IOException e) {
                        e.printstacktrace();
                }
        }

    }

}

有人可以告诉我如何在这里完成系统线程调用(事件和通知线程)以及导致死锁的事件序列.我不清楚这里涉及到导致死锁的线程是什么.

>有关于j2me线程模型的文档吗?
>我在哪里可以获得j2me系统类的源代码(我想查看Connection类的实现)?

编辑:在上面的代码中,我得到了逻辑.但是下面的代码应该至少可行吗?这个也在我在一个单独的线程中进行网络连接的地方死锁.

public class Foo extends MIDlet {

    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
        // Todo Auto-generated method stub
    }

    protected void pauseApp() {
        // Todo Auto-generated method stub
    }

    protected void startApp() throws MIDletStateChangeException {
        display display = display.getdisplay(this);
        MyCanvas myCanvas = new MyCanvas();
        display.setCurrent(myCanvas);
        myCanvas.repaint();
    }

    class MyCanvas extends Canvas {
        protected void paint(Graphics graphics) {
            try {
                Image bgImage = Image.createImage(getWidth(),getHeight());

                FetchImage fetchImage = new FetchImage();
                Thread thread = new Thread(fetchImage);
                thread.start();

                thread.join();

                bgImage.getGraphics().drawImage(fetchImage.image,0);

                graphics.drawImage(bgImage,0);
            } catch (Exception e) {
                // Todo Auto-generated catch block
                e.printstacktrace();
            }
        }
    }

    public class FetchImage implements Runnable {
        public Image image;

        public void run() {
            httpconnection httpconnection;
            try {
                httpconnection = (httpconnection) Connector
                        .open("http://10.4.71.200/stage/images/front/car.png");
                image = Image.createImage(httpconnection.openInputStream());
                httpconnection.close();
            } catch (IOException e) {
                // Todo Auto-generated catch block
                e.printstacktrace();
            }
        }

    }
}

解决方法

Where can I get the sources for
j2me system classes (I want to check
out the implementation of Connection
classes)?

你不能.它实际上依赖供应商.诺基亚处理这种情况的方式可能与摩托罗拉有所不同.

您必须学习的教训是,不要在系统回调中进行昂贵的计算,因为这可能会使系统无响应.因此,将耗时的操作放在一个单独的线程中,并尽可能早地从回调中返回.

即使你在第二个例子中创建了一个单独的线程,你也要等待它在paint()中的完成,它最终会导致没有线程的结果!

你能做的一件事是

class MyCanvas extends Canvas {

    Image image;
    boolean imageFetchFailed;

    protected void paint(Graphics g) {
        if (image == null) {
            fetchImage();
            g.drawString("Fetching...",getWidth() >> 1,getHeight() >> 1,Graphics.HCENTER | Graphics.TOP)

        } else if (imageFetchFailed) {
            g.drawString("Failed to fetch image",Graphics.HCENTER | Graphics.TOP)
        } else {
            g.drawImage(image,0);
        }
    }


    private void fetchImage() {
        new Thread(new Runnable() {
            public void run() {
                httpconnection httpconnection = null;
                try {
                    httpconnection = (httpconnection) Connector
                            .open("http://10.4.71.200/stage/images/front/car.png");
                    image = Image.createImage(httpconnection.openInputStream());
                } catch (IOException e) {
                    e.printstacktrace();
                    imageFetchFailed = true;
                }

                if (httpconnection != null) {
                    try {
                        httpconnection.close();
                    } catch (IOException ignored) {
                    }
                }

                // Following will trigger a paint call 
                // and this time image wont be null and will get painted on screen
                repaint();    
            }
        }).start();
    }
}

原文地址:https://www.jb51.cc/java/130141.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐