2017-02-16 4 views
0

Ein noch nicht freigegebener Java-Anwendungscode hat die folgende Struktur (dies ist an zahlreichen Stellen vorhanden). Die Klasse wird nur einmal während des Ladens des Anwendungskontexts geladen. Dies hat vorher gut funktioniert. Wenn Sie jedoch mit mehreren Threads in eine Regressionsumgebung wechseln, führt dies aufgrund der freigegebenen Elementvariablen zu Problemen mit dem gemeinsamen Zugriff.Ersetzen einer freigegebenen Elementvariable in einer Spring-Klasse

Class A { 

    private Set<String> codeSet = null; 

    public void method() { 

     codeSet = SomeRepo.someMethod(session.getUser()); // Heavy repo call, returns user specific data. 

     method1(); 

     method2(); 

     .... 

     methodn(); 
    } 

    private methodn() { 
     codeSet.iterator().next(); 
    } 
} 

Dieses Problem kann durch Änderung der variablen Rahmen des Verfahrens verringert werden, und nachdem er über alle nachfolgenden privaten Methoden geführt, die diese Variable verwenden. Dies beinhaltet jedoch viele Änderungen im Anwendungscode.

Gibt es eine saubere Lösung, die das unten ohne viel Änderungen auflösen kann. Danke im Voraus.

+0

Sie Thread Probleme erwähnt. zB Race Condition oder was? –

+0

die Variable kann durch gleichzeitige Threads zugegriffen werden, die Daten beschädigt werden –

+0

haben Sie versucht, Java ReentrantLock dieses Mitglied zu sperren, bis dieser bestimmte Thread damit oder Synchronisation abgeschlossen? –

Antwort

2

Ja, kann das Problem leicht durch Anwendung der folgenden Refactoring gelöst werden:

// singleton used by multiple threads 
class A { 

    public void method() { 
     Set<String> codeSet = SomeRepo.someMethod(session.getUser()); // Heavy repo call. 
     new AProcessor(codeSet).method(); 
    } 
} 

// not a singleton, only one thread uses an instance of this class 
class AProcessor { 
    private final Set<String> codeSet; 

    AProcessor(Set<String> codeSet) { 
     this.codeSet = codeSet; 
    } 

    public void method() { 
     method1(); 
     method2(); 

     .... 

     methodn(); 
    } 

    private methodn() { 
     codeSet.iterator().next(); 
    } 
} 
+0

+1 Dank .. scheint eine elegante Lösung sein, aber immer noch ein bisschen Refactoring beinhaltet. Wird auf andere Lösungen warten, bevor sie akzeptiert werden. –

Verwandte Themen