以下の単純な midlet コード (クラス Moo) (抜粋の後) はデッドロックします (少なくとも、スレッドに関するこの投稿を読んだ後はデッドロックになると思います)。
投稿から関連する抜粋を再現しました:
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("http://stackoverflow.com/content/img/so/logo.png");
Image image = Image.createImage(httpConnection
.openInputStream());
bgImage.getGraphics().drawImage(image, 0, 0, 0);
httpConnection.close();
graphics.drawImage(bgImage, 0, 0, 0);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ここでシステム スレッドの呼び出しがどのように行われるか (イベント スレッドと通知スレッド)、およびデッドロックにつながる一連のイベントを教えてください。ここでデッドロックにつながるスレッドが何であるかについては明確ではありません。
- j2me スレッド モデルに関するドキュメントはありますか?
- j2me システム クラスのソースはどこで入手できますか (接続クラスの実装を調べたいのですが)?
編集:上記のコードでは、ロジックを取得します。しかし、以下のコードは少なくとも正しく動作するはずですか? これは、別のスレッドでネットワーク接続を行っている場所でもデッドロックします。
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, 0, 0);
graphics.drawImage(bgImage, 0, 0, 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();
}
}
}
}