2010-07-23 10 views
0

J'ai une exigence qui devrait affecter une variable de compteur pour chaque thread qui est invoqué. Mais je n'obtiens pas les résultats attendus, en fait le compteur est en train de dupliquer dans les threads. J'ai créé une table fictive et un proc pour insérer la valeur du compteur dans la table. Est-il de toute façon que le code peut être modifié de sorte que le thread obtient une valeur incrémentée.Reg: Variable de compteur dans thread

Dans le code ci-dessous, la counter variable est un static int

public synchronized int testSequence(){ 
System.out.println("testSequence::::: "+counter++); 
//Random rn = new Random(); 
CallableStatement cstmt; 
{ 
    try { 
    cstmt = conn.prepareCall("{call insertjtest(?)}"); 
    cstmt.setInt(1,counter); 
    //cstmt.setInt(1, rn.nextInt()); 
    cstmt.execute(); 
    cstmt.close(); 
    conn.commit(); 
    return counter; 
    } catch (SQLException e) { 
    // TODO Auto-generated catch block 
    return 0; 
    } 
} 
} 

Mais je trouve le

+0

la question n'est pas complète et nous pouvons fournir une meilleure réponse si nous pouvons voir toute la classe. – nanda

Répondre

0

si vous voulez:

  • des routeurs indépendants pour chaque thread, vous pouvez utiliser un ThreadLocal variable ou une variable d'instance pour chaque objet de discussion
  • un compteur pour tous les threads, vous pouvez utiliser une AtomicInteger variables

EDIT: Après avoir vu votre code, il est un compteur pour tous les fils de discussion, de sorte que vous peut utiliser un AtomicInteger pour tous et il n'est pas nécessaire d'être synchronisé car AtomicInteger est un objet multithread.

+0

Ouais, essayé le même AtomicInteger et cela a fonctionné. Merci pour l'aide :) – Raghav

1

Je pense que vous pouvez simplement ajouter volatile à votre compteur

+0

fonctionne uniquement sur java> = 1.5, encore +1 – atamanroman

+0

yup mais AtomicInteger est surclassé dans ce cas et sur Java <1.5, vous n'avez pas non plus AtomicInteger: P – nanda

+0

Je pense que vous avez tort .. volatile ne peut être utilisé si la valeur à écrire ne dépend pas de la valeur actuelle! Sinon, cette solution pourrait conduire à un "problème de mise à jour perdue" .. (voir http://www.javamex.com/tutorials/synchronization_volatile_when.shtml) – Javaguru

1

Si j'ai bien compris votre question, vous voulez incrémenter la variable counter à chaque invocation du thread (ou sa méthode d'exécution). Ainsi, vous pouvez essayer quelque chose comme:

Thread myThread = new Thread(myRunnable) { 
    private int myValue; 
    public void run() { 
    // Call your "routine" .. 
    myValue = XXX.testSequence(); 
    super.run(); 
    } 
}; 
0

Vous voulez probablement faire de votre contre-valeur soit volatile, ou un AtomicInt - ce n'est pas garanti en Java que plusieurs threads verront immédiatement les mises à jour à des variables.