java – j2me网络,线程和死锁

前端之家收集整理的这篇文章主要介绍了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();
    }
}

猜你在找的Java相关文章