2012-02-14 12 views
26

I tipi di dati primitivi come int & short thread-safe in Java? Ho eseguito il codice seguente e non sono riuscito a visualizzare il risultato previsto 500 alcune volte.I tipi di dati primitivi thread-safe in Java

public class SampleThree extends Thread 
{ 
    static long wakeUpTime = System.currentTimeMillis() + (1000*20); 
    static int inT; 
    public static void main(String args[]) 
    { 
     System.out.println("initial:" + inT); 
     for(int i=0; i<500; i++) 
      new SampleThree().start(); 
     try { 
      Thread.sleep(wakeUpTime - System.currentTimeMillis() + (1000*30)); 
      System.out.println("o/p:" + inT); 
     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    public void run() 
    { 
     try { 
      long s = wakeUpTime - System.currentTimeMillis(); 
      System.out.println("will sleep ms: " + s); 
      Thread.sleep(s); 
      inT++; // System.out.println(inT); 
     } 
     catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Qui concomitanza 500 filetti aggiornerà la variabile int inT. Thread principale dopo aver atteso che l'aggiornamento simultaneo sia completato, stampa il valore inT.

Trova esempio simile here

+9

No, non sono thread-safe. Se hai intenzione di leggere solo, dovresti considerare di rendere il membro 'volatile'. Se hai intenzione di leggere e scrivere da diversi thread, dovresti renderlo 'synchronized' –

risposta

45

Ci sono tre modi in cui non sono sicura:

  • long e double non sono nemmeno garantiti da aggiornare atomico (si poteva vedere la metà di una scrittura da una filettatura diversa)
  • Il modello di memoria non garantisce che vedrete gli ultimi aggiornamenti da un thread in un altro thread, senza alcuna barriera di memoria aggiuntiva di alcun tipo
  • L'atto di incrementare una variabile non è atomico in ogni caso

Utilizzare AtomicInteger per operazioni thread-safe.

4

Suggerirei di utilizzare le classi in java.util.concurrent.atomic. Sono progettati per la sicurezza del thread e in alcuni casi la JVM può sfruttare le funzionalità hardware per ottimizzare.

10

I tipi primitivi non sono thread-safe. Verifica il tutorial this.

+0

Il punto chiave è che se una primitiva fosse definita come parte di un'istanza di un oggetto, quella primitiva sarebbe nell'heap, e non filo sicuro. – okwap

+2

È strano. La documentazione di Oracle in realtà dice che l'accesso di tipo primitivo è atomico per int: https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html – Yamcha

+1

@Parvin, Tranne per i caratteri long e double, i tipi primitivi sono garantiti per essere atomico. Se stai leggendo o scrivendo il valore, il suo thread è sicuro per quella operazione. – Pacerier

Problemi correlati