Sincronizzazione nel codice indicato

0

Ho avuto un'intervista qualche settimana fa e mi è stato chiesto di scrivere un codice con Setters and Getters. Ho scritto il seguente codice;

// Just an example

Class ABC{
    private int num;

    public void setNum(int givenNum){
        this.num = givenNum;
    }

    public int getNum(){
        return num;
    }

    public ABC(){
        num = 0;
    }


    public static void main(String [] args){
        ABC object1 = new ABC();
        ABC object2 = new ABC();

        object1.setNum(5);
        System.out.println(object1.getNum());
        System.out.println(object2.getNum());
    }

}

Ora mi è stato detto che "oggetto1" può cambiare il valore di "oggetto2.Num". Ma non ero d'accordo con questo, credo che un altro thread che ha accesso a object2 possa cambiare il valore di object2.Num ma non object1.

Nel caso precedente, avrei sincronizzato il metodo setter, o usato il blocco sincronizzato all'interno del metodo setter durante l'impostazione / modifica del valore, ma non riuscivo a capire il concetto di oggetto1 cambiando il valore dell'oggetto2.Num.

Ero solo curioso di sapere se mi mancasse qualcosa. Se è così, apprezzerei davvero qualsiasi aiuto per quanto riguarda lo stesso.

    
posta JNL 05.07.2013 - 15:29
fonte

3 risposte

0

Se è possibile accedere alla classe ABC da più thread, dovrai sincronizzare sia setNum che getNum . Fino a quando non lasci un blocco di sincronizzazione, il nuovo valore di num non deve essere disponibile per nessun altro thread. Finché non si inserisce un blocco di sincronizzazione, le modifiche apportate in un altro thread non saranno visibili in questo. E in Java (ma non in C #), entrambi i blocchi devono (secondo le regole, JLS) essere sincronizzati sullo stesso oggetto. (Naturalmente, se crei i metodi synchronized , si sincronizzeranno bene su questa istanza di ABC.)

Questo potrebbe essere stato il punto che il tuo intervistatore stava facendo.

(E rendere "num" volatile ( private volatile int num ) farebbe la stessa cosa).

    
risposta data 05.07.2013 - 20:41
fonte
3

Se tutto ciò che hai è un riferimento a object1 , quindi no, non puoi modificare object2.num .

L'unica cosa che viene in qualche modo vicina a ciò che descrivi è simile a questa:

public void swap(ABC other) {
  int num = this.num;
  this.num = other.num;
  other.num = num
}

Suche un codice può modificare due ABC oggetti: this (cioè l'oggetto sul quale è chiamato) e other (il parametro). Ma questo non ha nulla a che fare con il multithreading.

    
risposta data 05.07.2013 - 15:44
fonte
2

La sincronizzazione non è il concetto pertinente qui. Si sincronizzano le cose per evitare errori causati dall'imprevisto ordine di azioni causato dall'interlacciamento di thread diversi. L'esempio classico è la riduzione del saldo di un conto bancario e l'aumento di un altro dello stesso importo, che può perdere informazioni (denaro) se non fatto atomicamente. Ma questo codice assegna semplicemente un numero intero, che è già atomico, quindi il punto non è incoerenza.

Probabilmente stavano parlando di controllo degli accessi e il fatto abbastanza sorprendente che private significa "privato per tutte le istanze della classe" e non "privato per l'istanza proprietaria solo" in java. object2 può cambiare il valore di un campo in object1 se ha un riferimento a object1 . Ma questo non ha nulla a che fare con la sincronizzazione.

    
risposta data 05.07.2013 - 15:46
fonte

Leggi altre domande sui tag