Bentornati.
Abbiamo introdotto il database Builder e abbiamo passato i tre parametri:
il contesto, il tipo di database e il nome del database.
Ma questo non è un approccio molto professionale.
Dobbiamo creare una sola istanza del nostro database, evitando
istanze multiple di database e perdite di memoria.
Esiste una sola istanza del database, evitando così un
inutile sovraccarico associato alla creazione ripetuta del database.
Seguiremo quindi un modello chiamato singleton design pattern.
Vorrei che vi concentraste su questo punto perché è un argomento molto importante per la creazione di un database.
All'inizio.
Inizio con una variabile astratta di note.
Dao e di seguire il design pattern singleton, che
prevede l'esistenza di una sola istanza del database.
Per evitare l'inutile overhead associato alla creazione ripetuta di un DB,
è necessario utilizzare due importanti parole chiave: companion object e volatile.
Cominciamo con l'oggetto compagno.
Oggetto compagno.
In Kotlin, l'oggetto companion è un oggetto singleton associato a una classe.
È possibile accedere ai membri di questo oggetto utilizzando il nome della classe senza creare un'istanza della stessa.
Qui abbiamo bisogno che l'oggetto companion contenga l'istanza singleton.
La logica per ottenere o creare il database.
All'interno di questo oggetto companion, dobbiamo creare una nuova variabile chiamata instance.
È di tipo node db ed è uguale a null.
Mark this instance with volatile Questa variabile contiene un
riferimento alla singola istanza del database DB del nodo.
Inizialmente è impostato su null, a indicare che il database non
è ancora stato creato e per questo si usa l'annotazione volatile.
La volatilità impedisce qualsiasi condizione di gara in scenari di multithreading in un ambiente multithread.
Senza volatilità, è possibile che un thread legga il valore di
stato di un'istanza mentre un altro thread l'ha già inizializzata.
L'annotazione volatile evita questo problema, garantendo che il valore sia visibile in modo coerente in tutti i thread.
Immaginiamo due thread, il thread A e il thread B, che cercano entrambi
di accedere alla variabile di istanza per ottenere l'istanza del database senza volatilità.
Senza l'annotazione volatile, il thread A legge l'istanza come nulla e
inizia a inizializzare il database prima che il thread A finisca.
Filetto B.
Inoltre, leggendo l'istanza come null e poiché il valore non è stato aggiornato nella cache, entrambi
i thread finiscono per creare istanze separate del database, vanificando lo scopo di avere un singleton.
Abbiamo quindi due fili.
Due thread cercano di creare istanze di database e alla fine abbiamo
due database, due versioni diverse di database, due istanze di database.
Questo ci impedirà di avere un unico database per
la nostra applicazione, utilizzando il thread di annotazione volatile.
A legge l'istanza come nulla e inizia a inizializzare il
database un thread A scrive l'istanza del database inizializzata all'istanza.
La parola chiave volatile assicura che questa modifica sia immediatamente visibile a tutti gli altri thread.
Ad esempio, il thread B legge il valore aggiornato dell'istanza e vede che
il database è già inizializzato, impedendo la creazione di una seconda istanza.
In questo modo si impedisce al thread B di creare un'altra istanza
del nostro database, ottenendo così un solo database per l'intera applicazione.
Occorre quindi creare una nuova funzione, chiamata get instance,
per restituire un'istanza dell'oggetto contesto fornito dal database.
Nota.
DB.
Importare il contesto e all'interno di questa funzione occorre restituire l'inizializzazione dell'istanza, se non
è ancora stata creata, oppure restituire l'istanza del database, se è stata creata.
Quindi dobbiamo usare la parola chiave synchronized e dobbiamo usare questo synchronized.
E lo abbiamo passato nella creazione del database della stanza.
E assicurarsi che solo un thread possa essere eseguito.
Il blocco di codice all'interno del blocco sincronizzato in qualsiasi momento è molto importante.
Questo è molto importante per evitare che vengano create
istanze multiple del database della stanza in ambienti multi-thread.
Abbiamo quindi usato la parola chiave synchronized per eseguire il codice una sola volta
in un determinato momento, solo un thread può accedere, creare ed eseguire questo codice.
All'interno di questo codice dobbiamo creare una var instance uguale a instance che abbiamo creato in precedenza.
Occorre quindi verificare se questa istanza è uguale a null.
Quindi, se è nullo, si esegue questo blocco di codice.
Qui dobbiamo usare il nostro codice per creare l'oggetto database.
Tagliatelo e incollatelo qui.
Qui si crea un'istanza dell'oggetto database.
Rimuovere la var e impostare questa istanza sull'istanza creata qui.
Quindi, ragazzi, se il database è nullo, andate a crearne uno.
Altrimenti, restituire l'istanza come istanza e restituire l'istanza in entrambi i casi.
Qui abbiamo un errore richiesto database camera trovato note db.
Se saliamo possiamo notare che si tratta di un'annotazione di database.
Inoltre, è necessario estendere il database della stanza.
Ok, in questo modo diciamo ad Android Studio che il DB delle note
fungerà da database con queste entità e si estenderà dal database della stanza.
Ok, questo è il modello di progettazione dei singleton.
In questo modo si crea un oggetto companion.
In questo modo si crea un'istanza del database della stanza e si accede a un solo thread in qualsiasi momento