Domanda

Sto usando un po 'di libreria di terze parti per la connessione a un server tramite il protocollo asincrono e ottenere risposta indietro. Per il metodo esempio per ottenere userid per nome utente simile a questo:

public int getUserid(String username) {
        int userid = 0;

    connection.call("getUserid", new Responder() {
        public void onResult(final int result) {
            System.out.println("userid: " + result);
            //how to assign received value to userid and return it?
        }
    }, username);

    //wait for response
    while (userid == 0) {
            try{
                Thread.sleep(100);
            } catch (Exception e) {}
        }


        return userid;
}

Il problema è che non è possibile assegnare tornato "risultato" dalla risposta del server a "userid" variabile dal metodo (al fine di restituirlo dopo). Come risolvere questo problema? Probabilmente posso assegnarlo a una variabile di classe piuttosto che variabile metodo ma voglio mantenerlo entro il metodo di applicazione in modo da non avere a che fare con problemi di concorrenza.

Grazie.

È stato utile?

Soluzione

Se ho capito bene la tua domanda, si sta chiedendo come si può scrivere una variabile dall'interno di una classe anonima.

classi anonimi possono accedere solo le variabili finali, e non può direttamente "scrittura" di loro.

Una soluzione semplice che è "abbastanza buono" è quello di creare una sorta di una classe ValueBox con un singolo campo di valore e un getter e setter. È quindi possibile creare un'istanza di uno nuovo in funzione come una variabile finale, ed avere l'accesso anonimo classe di esso. La classe anonima userà la sua getter e setter di scrittura / lettura.

Il fatto che la variabile è definitiva significa solo che non si può puntare il riferimento in qualsiasi altro luogo, ma è ancora possibile modificare il contenuto dell'oggetto di cui da entrambe le funzioni.

Il problema più grande che si sta per avere è in attesa fino a quando la richiamata è stato chiamato. Questo tipo di attesa sonno potrebbe essere abbastanza buono, ma si può prendere in considerazione i timeout, fili, ecc, a seconda di ciò che si sta cercando di raggiungere.

Inoltre, tutto questo presuppone che si sta andando mai a chiamare due volte sulla connessione. In caso contrario, è necessario fornire ulteriori informazioni per sul vostro modello di sincronizzazione.

Ecco alcuni esempi di codice:

public int getUserid(String username) {
        final ValueBox<Integer> userid = new ValueBox<Integer>();

        connection.call("getUserid", new Responder() {
                public void onResult(final int result) {
                        System.out.println("userid: " + result);
                        userId.setValue(result);
                        //how to assign received value to userid and return it?
                }
        }, username);

        //wait for response
        while (userid.isEmpty()) {
                try{
                        Thread.sleep(100);
                } catch (Exception e) {}
        }

      return userid.getValue();
}

Altri suggerimenti

La modifica più semplice è quello di usare qualcosa come java.util.concurrent.SynchronousQueue. Ma forse si vuole fornire un evento guidato interfaccia te stesso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top