2

私のj2me Javaアプリには、オブジェクトを初期化するスレッドがあり、その直後に他のクラスの値を返すことによって取得する必要があります。

その直後にスレッドを呼び出すメインクラスでは、スレッドで変更された値を取得する必要がありますが、スレッドが完了する前に関数が呼び出され、null が返され、プログラムが続行されないという問題が発生します。

私がしたことは、ブール値のステータスがスレッド内で真にならないまでその戻り値を待機させることでしたが、そのため while ループがそこにハングアップし、戻ってきません。

以下のコードを投稿して、最善の解決策を教えてください。このコードは J2me (Java) にあり、スレッドでも機能が制限されていることを覚えておいてください。

値を返すための Thread およびその他の関数を次に示します。

public synchronized void run() {
    try {
        contacts.removeAllElements();
        pim = PIM.getInstance();
        String lists[] = pim.listPIMLists(PIM.CONTACT_LIST);
        for (int i = 0; i < lists.length; i++) {
            //code for custom backup operation
            if (customCode == 1 && i == 0) {
                continue;
            } else if (customCode == 0 && i > 0) {
                continue;
            }
            clist = (ContactList) pim.openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE, lists[i]);
            Enumeration cenum = clist.items();
            while (cenum.hasMoreElements()) {
                Contact c = (Contact) cenum.nextElement();
                ContactDTO contact = new ContactDTO();
                parseContactInfo(c, contact);
                contacts.addElement(contact);
            }
            clist.close();
        }
        readComplete = true;
    } catch (Exception e) {
    }
}

//Return contacts loaded into vector list
public ContactVector getLoadedContacts() {
    while(!readComplete){
         Thread.sleep(100);
        }
     return contacts;
}

これは、私がこれを呼び出さなければならないメインクラスです

public ContactVector getContactVector() {
    DeviceContactRetriever dcr = new DeviceContactRetriever(this, language);
    dcr.start();
    ContactVector vector = dcr.getLoadedContacts();      //problem line*
    return vector;
}

*problem 行は完了する前にオブジェクトを返すため、null になります。

4

1 に答える 1

-1

あなたの問題は、コードが同期されていないことです。

以下のように、メソッドwait()とを使用する必要があります。notify()

public synchronized void run() {
    try {
        contacts.removeAllElements();
        //...
        readComplete = true;
        this.notify();
    } catch (Exception e) {
    }
}

//Return contacts loaded into vector list
public synchronized // <-- note sync'd here
        ContactVector getLoadedContacts() {
    while(!readComplete){
         this.wait();
        }
     return contacts;
}

これはかなり基本的なことです。並行性に関する Java チュートリアルを検討してください。

可能であれば、Java 5 より前のバージョンの Java のチュートリアルを探してください。そうしないと、Java ME (現時点では Java 1.3 に限定されています) で使用できるものの説明が最新の機能と「混在」し、最新の機能を学ぶのが難しくなります。あなたに関連します。

私にとってそのように機能したチュートリアルの例は、Jacob Jenkov hereによるもので、「はじめに...」から「スリップした状態」までの章が含まれています。以降の章 (「ロック」など) も悪くはありませんが、これらは Java 5 以降に導入された機能 (JSR 133 / 166 - JMM および同時実行ユーティリティ) に大きく依存していることに注意してください。


上記で説明したバグに関連しないコードに関するいくつかの観察。

  1. あなたのコードは非常に複雑なので、ログメッセージを追加してデバッグを容易にすることを検討してください (ここで説明されているように)。特に、catch ブロックの例外のようなものをログに記録することを強くlistsお勧めします (理由に興味がある場合は、Web で _Java のようなものを検索して例外を飲み込まないでください)。そのサイズとclistcenumおよびcが null かどうか。

  2. およびループ内のスニペットにあるコードを別のメソッド (ここで説明されているように) に抽出することで、コードを読みやすく変更しやすくすることを検討してください。forwhile

  3. コードのgetContactVector()実行には時間がかかる可能性があるため、UI スレッドから呼び出すことは避けたほうがよいことに注意してください。その理由と正しい方法を理解したい場合は、lcdui tag wikiで参照されているチュートリアル「Networking, User Experience, and Threads」を確認してください。

于 2013-01-18T09:54:28.027 に答える