Prosty kawałek kodu pośredniego (klasa Moo) poniżej (po fragmentach) zakleszczenia (Przynajmniej zakładam, że zakleszczenia po przeczytaniu tego postu na wątki here).sieci j2me, wątki i zakleszczenia
Mam reprodukowane odpowiednich fragmentów ze stanowiska:
String url = ...
Connection conn = null;
try {
conn = Connector.open(url);
// do something here
}
catch(IOException e){
// error
}
Źródłem problemu jest natura blokowanie open() rozmowy. Na niektórych platformach system wykonuje rzeczywiste połączenie pod osłonami, w równoważnym oddzielnym wątku. Wątek wywołania blokuje się, dopóki wątek połączenia nie ustanowi połączenia. W tym samym czasie podsystem bezpieczeństwa może wymagać od użytkownika potwierdzenia połączenia, a wątki połączeń bloków do momentu, aż wątek zdarzenia zostanie potwierdzony przez użytkownika. Zakleszczenie występuje, ponieważ wątek zdarzenia już czeka na wątek połączenia.
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();
}
}
}
}
Czy ktoś mógłby mi powiedzieć jak inwokacja wątek systemu odbywa się tutaj (zdarzeń i powiadamiania wątków) i sekwencję zdarzeń prowadzących do impasu. Nie mam jasności co do tego, o co chodzi w wątku, który prowadzi do impasu.
- Czy istnieje dokumentacja dotycząca modelu nici j2me?
- Skąd mogę pobrać źródła dla klas systemowych j2me (chcę sprawdzić implementację klas połączeń)?
EDIT: W powyższym kodzie otrzymuję logikę. Ale poniższy kod powinien przynajmniej działać poprawnie? Ten także zakleszcza się, gdy robię połączenie sieciowe w osobnym wątku.
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();
}
}
}
}
Doskonałe pytanie i odpowiedź, szczególnie jeśli naprawdę chcesz uzyskać pewną klarowność. – Sydwell