2013-06-03 16 views
5

Come risponderesti alla seguente domanda?esegui atomicamente un blocco di codice

Un metodo di una classe java contiene un blocco di codice che deve essere eseguito atomicamente. Spiegate, utilizzando appropriati pseudo-codice, come si garantirebbe che questo blocco di codice viene eseguito in modo atomico

Dovrei raggiungere questo obiettivo facendo il metodo ..

public final AtomicInteger x = new AtomicInteger(0); 

quindi garantire l'istruzione Get restituita :

x.get() 

e se volessi incrementare il valore di x lo farei?

x.getAndIncrement(); 
+3

Atomicamente rispetto a cosa? – SLaks

+0

scusa non sono sicuro, questo è tutto ciò che abbiamo per la domanda. è una domanda d'esame passata e non ci è stata data risposta ad esempio – germantom

+1

Questa domanda è troppo vaga per poter rispondere. – SLaks

risposta

32

La risposta dipende dalla vostra definizione di "atomica"

So di tre definizioni valide per atomic:

  1. atomica come nel sincronizzato: solo un thread può essere in esecuzione il codice in una sola tempo;
  2. Atomico come in ACID: avviene tutta l'azione/blocco o nessuna di esse;
  3. Atomico come in uninterruptible: una volta avviato il blocco, non può essere interrotto, nemmeno dalla commutazione di attività.

Il primo è probabilmente ciò che intendeva il tuo professore, ed è piuttosto facile da realizzare (vedi sotto).

Il secondo (atomico come in ACID) può essere approssimato. Vedi sotto.

Il terzo semplicemente non può essere garantito in Java: non fornisce l'accesso alle primitive "sezioni critiche" richieste per l'interruzione. Fortunatamente, la necessità di questo è praticamente limitata ai sistemi operativi e ai driver di periferica.

atomica come nel sincronizzato

Questo è relativamente semplice: bisogna scrivere il vostro blocco di codice in un blocco sincronizzato.Ho mostrato come un blocco digitale di sotto, ma ci sono altre opzioni:

public void doSomethingQuasiAtomic() { 
    synchronized (exampleLock) { 
     // Your code block goes here. 
     // Only one thread will ever be in this block at a time. 
     ... 
    } 
} 

atomica come in acido

Non c'è soluzione generale per caso per ACID atomicità, ma può essere approssimata, anche usando il codice sincronizzato. Per fare ciò, ciascuna delle parti dell'azione deve essere reversibile in modo sicuro.

Questo è come mi piacerebbe avvicino:

Per amor di discussione, presumo c'è un'azione più parti è necessario fare su un oggetto che chiameremo exampleObj, che avete tre azioni da compiere che può essere protetto in modo sicuro e che tutti gli accessi a example siano sincronizzati su exampleLock.


    synchronized(exampleLock) { 
     boolean actionOneDone=false; 
     boolean actionTwoDone=false; 
     boolean actionThreeDone=false; 
     try { 
      actionOneDone=doActionOne(exampleObj); // or perhaps exampleObj.doActionOne(); 
      actionTwoDone=doActionTwo(exampleObj); 
      actionThreeDone=doActionThree(exampleObj); 
     } catch (Exception ex) { 
      // Whatever seems appropriate here. 
     } finally { 
      if (! (actionOneDone && actionTwoDone && actionThreeDone)) { 
       /* At least one part failed. Back out the completed actions in reverse order. 
       * Note that we never need to reverse action three since if it completed, so did the others. 
       */ 
       if (actionTwoDone) { 
        reverseActionTwo(exampleObj); // or perhaps exampleObj.reverseActionTwo(); 
       } 
       if (actionOneDone) { 
        reverseActionOne(exampleObj); 
       } 
      } 
     } 
    } 
+0

Interessante! Vedo solo me stesso dare questo come una risposta di prova: P – Mifeet

+0

ben messo, signore! chiaro e conciso. –

1

credo che la risposta attesa era qualcosa di simile:

public class A { 
    public void foo() { 
     // .. some code 
     doSomething(); // the critical part 
     // .. come code 
    } 

    public synchronized void doSomething() { // this is a synchronized method 
     // the critical code 
    } 
} 

L'esecuzione di doSomething() in realtà non è atomica (Esonero di responsabilità: è molto diverso da atomicità), ma i synchronized assicura parola chiave che solo un thread può accedere all'esecuzione di questo metodo (su un'istanza di A). Penso che sia quello che intendevano invece di atomicità.

Here è un'altra domanda sull'atomicità in Java. Potresti trovare qualcosa di utile lì.

+1

Questo è molto diverso dall'atomicità. Altre funzioni possono ancora osservare l'oggetto in uno stato incoerente. – SLaks

+1

Probabilmente è a questo che si riferiva la domanda, ma un metodo 'sincronizzato' non garantisce in alcun modo l'atomicità. –

+1

Sì, ma la domanda ovviamente non ha senso, quindi penso che sia poco espressa. Penso che intendessero l'atomicità nel senso che l'interleaving delle istruzioni nel blocco "atomico" è escluso. So che non è una vera atomicità, ma parlano di "blocchi di codice", quindi probabilmente non intendevano nemmeno "AtomicInteger" o altro. – Mifeet

Problemi correlati