Come mantenere lo stato sincronizzato tra thread: è un buon uso per Singleton?

7

Ho sentito parlare di "Singletons sono sempre cattivi" in giro per il posto. Non li odio fino a quel punto, ma cerco di non usarli se ho un'alternativa migliore.

In questo caso ho un sistema che gestisce molte richieste, ognuna delle quali entra in una sua discussione. Ogni richiesta che arriva deve essere assegnata al proprio ID sequenziale unico.

Attualmente ho una classe Singleton il cui ruolo è avviare questo Id all'avvio e mantenerlo mentre il sistema è in esecuzione. Il Singleton viene creato / recuperato e il valore Id viene incrementato in modo thread-safe, come ci si aspetterebbe. In realtà viene distribuito ai thread sulla creazione da Dependency Injection, ma il nucleo della classe è un Singleton classico costruito intorno a una rappresentazione statica del valore di Id corrente.

Dato che è probabile che facciamo più lavoro che richiede un approccio multi-thread, sarei interessato a sapere se c'è un modo per implementare questo tipo di funzionalità in un modo che permetta di mantenere i dati in modo sincrono attraverso fili altrimenti inconsapevoli l'uno dell'altro, senza usare il modello Singleton tanto temuto?

    
posta glenatron 20.03.2013 - 15:44
fonte

2 risposte

4

C'è una differenza tra un singleton e un'istanza che può essere condivisa tra più client. Sembra che tu voglia il secondo (se no, ripensaci!). Per questo, un singleton non ha alcun vantaggio e molti dei soliti aspetti negativi. Permetti semplicemente un numero qualsiasi di istanze, ma in realtà non ne crei più quando vuoi condividere. Hai già l'infrastruttura giusta per questo (passando l'oggetto tramite l'integrazione delle dipendenze). Probabilmente hai solo bisogno di rendere pubblico il costruttore e di eliminare l'infrastruttura singleton.

Quindi non costa praticamente nulla e ottieni:

  • Semplicità: fortunatamente, non fare qualcosa di singleton è leggermente più semplice che renderlo un singleton.
  • Testabilità: quando vuoi testare qualcosa che coinvolge questo ID allocator, puoi semplicemente crearne uno nuovo invece di dipendere da uno stato globale di qualche singleton.
  • Estensibilità: se a un certo punto hai bisogno di più fonti indipendenti di ID sequenziali in un unico processo, puoi semplicemente creare un'altra istanza.
risposta data 20.03.2013 - 15:57
fonte
1

Avendo un singleton, aggiungerai la creazione di singleton, l'accesso e la manipolazione dello stato ai tuoi problemi di multithreading.

Inoltre, supponi che il tuo gestore di richieste ne abbia solo uno nell'intero sistema. Questo non è corretto Sì, potresti averne bisogno solo ora. Ma per quanto riguarda i test unitari? Sei non intenzione di eseguirli contemporaneamente? Che dire dei sottosistemi che alla fine potrebbero volere la loro richiesta di spedizione? Che dire della possibilità di decorare o compositare quella spedizione?

No, hai qualche oggetto che accetta richieste e assegna loro un ID per quel gestore. Se cambiano gli ambiti, puoi semplicemente ri-identificarne la richiesta o disporre di un unico provider di ID condiviso per i diversi gestori di richieste.

    
risposta data 20.03.2013 - 15:54
fonte

Leggi altre domande sui tag