La première: l'utilisation du mot-clé synchronisé
Étant donné que chaque objet de la java a un verrou intégré, lorsque vous utilisez ces méthodes de modification de mots clés, verrous intégrés protègent toute la méthode. Avant d'appeler cette méthode, vous devez obtenir le verrouillage intégré, sinon il est bloqué.
Remarque: les méthodes statiques de mot-clé synchronisé peuvent également être modifiées, si l'appel de méthode statique à ce moment, il se verrouille toute la classe.
La synchronisation est une opération coûteuse de haut, et devrait donc être réduit au minimum la synchronisation. Il est généralement pas nécessaire de synchroniser l'ensemble de synchronisation de bloc de code synchronisé de la méthode utilisant le code clé.
1. La méthode de synchronisation: une méthode pour augmenter après le modificateur synchronisé peut rendre une méthode de synchronisation, cette méthode peut être des méthodes statiques et non statiques, mais ne peut pas être méthode abstraite classe abstraite, ni l'interface de méthode d'interface.
Lors de l'exécution procédé de synchronisation de fil est d'avoir une exclusivité. Lorsque l'un quelconque fil d'entrer dans un quelconque d'un procédé de synchronisation d'un objet, l'objet de toutes les méthodes de synchronisation ont été verrouillée,
En attendant, tout autre thread peut accéder à tout objet d'une méthode de synchronisation, jusqu'à ce que ce fil a terminé la mise en œuvre de la méthode de synchronisation appelle et la sortie,
L'amenant à libérer le verrou de l'objet après la synchronisation. Une fois qu'un objet est verrouillé, un fil, tous les autres fils sont méthode asynchrone peut accéder à l'objet.
2. Le bloc de synchronisation: des blocs de synchronisation est réalisée par verrouillage d'un objet spécifié inclus dans la synchronisation de code de synchronisation de bloc, et ce procédé est un procédé de synchronisation dans le code de synchronisation de bloc, et le verrouillage de l'objet dans ce cas est la synchronisation la principale méthode d'objet appartient à lui-même.
Si cette méthode est de façon synchrone statique pour le faire? Puis le verrou de fil sur l'objet de cette classe n'est pas, ni
La classe elle-même, mais correspondant à des objets de ce type de classe java.lang.Class. Les interactions entre procédé de synchronisation de bloc de synchronisation et confiné entre le même objet, il est seulement limité par la méthode de la statique de la synchronisation de la classe appartient à un autre procédé de synchronisation de statique, à l'instance (objet) de cette classe n'a pas d'importance.
Si un objet est à la fois la méthode synchrone, un autre bloc synchronisé, puis lorsque l'un quelconque d'un procédé synchronisé ou bloc synchronisé est exécuté un fil, l'objet est verrouillé, d'autres fils ne peut pas accéder à la méthode de synchronisation de cet objet à ce moment, bloc de synchronisation ne peut pas être exécuté.
mot-clé synchronisé est utilisé pour protéger les données partagées. S'il vous plaît noter que « données partagées », il faut faire la distinction entre ce que les données sont données partagées.
Package Frais de pénalité pour com.gcc.interview.synchro; / ** * Créer un fil * @author gcc * * 2018 Nian 3 Yue 9 Ri * / publique classe MybanRunnable les outils Runnable { Private Bank Bank, publique MybanRunnable (Bank Bank) { la présente .bank = Banque; } @Override publique vide RUN () { pour ( int i = 0; I <10; I ++ ) { bank.save1 ( 100 ); System.out.println ( "solde du compte est ---" + bank.getAccount ()); } } }
Paquet com.gcc.interview.synchro; / ** * Des exemples de dépôts bancaires * @author GCC * * date 2018 ans 3. 9 jours. * / Class Banque { Private int compte = 100 ; publique int la getAccount () { retour compte; } / / méthode de synchronisation publique synchronisée vide Save ( int argent) { compte + = argent; } publique vide ENREG.1 ( int argent) { // bloc synchronisé synchronisé( Ce ) { compte + = argent; } } Publique vide userThread () { banque Bank = nouvelle banque (); MybanRunnable my1 = nouveau MybanRunnable (banque); System.out.println ( "线程1" ); Discussion Th1 = nouveau fil (my1); th1.start (); System.out.println ( "线程2" ); Discussion Th2 = nouveau fil (my1); th2.start (); } }
La seconde: wait et notify
wait (): faire un fil dans un état d'attente et libère le verrou tenu par l'objet.
sleep (): faire un fil conducteur dans un état de sommeil, il est un appel de méthode statique cette méthode pour la capture exception InterruptedException.
Notify (): réveiller un fil dans un état d'attente, en notant qu'au moment où cette méthode est appelée, ne état d'attente se réveille pas exactement jusqu'à un fil, mais qui est déterminé par le fil machine virtuelle Java se réveille, mais pas par priorité.
Allnotity (): Réveiller un fil dans un état d'attente du tout, noter que réveiller tout fils pour verrouiller un objet, mais laissez-les en concurrence.
Troisièmement: l'utilisation de la variable spéciale de domaine volatile mettre en œuvre la synchronisation des threads
1.volatile mot - clé permet d' accéder au domaine d'un mécanisme de verrouillage de la variable libre;
2. Utiliser la région volatile équivalente à modifier la machine virtuelle pour indiquer ce domaine peuvent être mis à jour par d' autres fils;
3. donc nécessaire de recalculer à chaque utilisation du domaine , plutôt que d' utiliser les valeurs de registre,
4.volatile fourni aucune opération atomique, il ne peut pas être utilisé pour modifier le dernier type de variable,
par exemple:
dans l'exemple ci - dessus eux, juste en face du compte ainsi que des modifications volatiles peuvent mettre en oeuvre la synchronisation des threads.
// donne uniquement le code à modifier, et le reste du code avec la classe Banque { // besoin de variables Synchronize , plus volatile privée volatile int compte = 100 ; publique int la getAccount () { retour compte; } // n'est ici plus nécessaire la synchronisation publique vide Save ( int argent) { compte + = argent; } }
Quatrièmement: utiliser des verrous réentrants pour la synchronisation du fil
Ajout d' un paquet java.util.concurrent dans JavaSE5.0 en synchronisation de support.
classe ReentrantLock est rentrante, exclusif, pour obtenir verrouillage interface de verrouillage, il est rapide et l' utilisation de méthodes synchronisées ont le même comportement de base et la sémantique, et sa capacité à se développer.
méthode commune classe ReenreantLock sont:
ReentrantLock (): créer une instance de ReentrantLock
verrouillage (): obtenir le verrouillage
déverrouillage (): libérer le verrou
Note: ReentrantLock () peut également créer une méthode de construction de verrouillage juste, mais peut réduire de manière significative le programme d'efficacité, non recommandé
privé int compte = 100 ;
privé serrure ReentrantLock = nouvelle ReentrantLock ();
publique int getAccount () { retour compte; } // 同步方法 publique vide save ( int argent) { serrure.Serrure (); essayez { compte + = argent; } Enfin { lock.unlock (); } }
Remarque: verrouillage sur l' objet sélectionné et le mot - clé synchronisé:
A deux meilleurs ne sont pas dans le paquet java.util.concurrent utilise un mécanisme prévu pour les utilisateurs aider à composer avec tout le code de verrouillage.
. B Si le mot - clé synchronisé pour répondre aux besoins des utilisateurs, utiliser synchronisés, car il peut simplifier le code;
. C Si vous avez besoin de fonctionnalités plus avancées, classe l' utilisation de ReentrantLock, cette fois -ci à faire attention à la libération rapide de la serrure, sinon il y aura une impasse, verrouiller habituellement dans un finalement libéré.
Cinquième: Utiliser des variables locales pour mettre en œuvre la synchronisation des threads
ThreadLocal (): Crée une variable locale fil valeurs retournées cette copie locale de thread du thread courant: GET () initialValue (): Renvoie les variables locales de thread de l'thread courant « valeur initiale » SET (valeur T): cette les valeurs dans les années actuelles de fil copie des variables locales de thread à valeur
// changement que la classe Banque, et le reste du code avec le publique classe Bank { // Utilisation de la classe ThreadLocal gère la variable partagée Compte privé statique ThreadLocal <Entier> = Compte nouveau nouveau ThreadLocal <Entier> () { @Override protégé Entier initialValue () { retour 100 ; } };
publique vide Save ( int argent) { account.set (account.get () + argent); }
publique int la getAccount () { retouraccount.get (); } }
Sixième: bloquer la mise en oeuvre des files d'attente en utilisant la synchronisation des threads
Devant cinq types de méthode de synchronisation des threads est la mise en œuvre sous-jacente de synchronisation, mais nous sommes en fait dans le développement, il devrait être aussi loin de la structure sous-jacente.
Utilisez la version javaSE5.0 du nouveau package java.util.concurrent aidera à rationaliser le développement. Cette section principalement en utilisant LinkedBlockingQueue <E> pour synchroniser les threads LinkedBlockingQueue <E> est une file d'attente éventuellement de blocage sur la base des noeuds connectés.
FIFO sont pour les files d'attente (FIFO), la file d'attente sera expliquée en détail par la suite ~ LinkedBlockingQueue méthode classe commune LinkedBlockingQueue (): Crée une capacité de Integer.MAX_VALUE LinkedBlockingQueue mis (E e):
Ajout d'un élément dans la queue, si la file d'attente est la taille de blocage complet (): Renvoie le nombre d'éléments prennent la file d'attente (): supprime et retourne le premier élément de l'équipe, si la file d'attente est des exemples de code de blocage vides: les entreprises à réaliser la production du commerce des biens et des marchandises synchronisation
Note: BlockingQueue <E> définit une méthode commune de file d'attente de blocage, et trois en particulier la méthode des éléments additifs, nous devrions accorder plus d'attention lorsque la file d'attente est pleine:
Procédé ajouter () renvoie une exception
le retour de la méthode d'offre () faux
mettre () des blocs de procédé
Septième: mettre en oeuvre la synchronisation des threads avec des variables atomiques
Les mensonges sur les causes profondes de l'opération de synchronisation de fil nécessaire à l'utilisation ne sont pas des atomes de variables ordinaires.
Alors, quelle est une opération atomique il? opération atomique se réfère à la valeur de la lecture variable, modifier les valeurs variables pour les variables dans son ensemble qui est à utiliser - ces types de comportement sont soit effectuées simultanément, ou aucun d'entre eux est terminée.
Fournir des outils créer des types atomiques des variables du paquet java util.concurrent.atomic, simplifie l'utilisation d'une telle synchronisation des threads. Table AtomicInteger peut être caractérisé en ce jour la valeur atomiquement int,
Peut être utilisé dans des applications (telles que incrémenter atomiquement un compteur), mais ne peut pas être utilisé pour remplacer Integer; évolutifs Nombre, outils et utilitaires qui permet la possibilité de traiter les classes d'accès numérique uniforme.
AtomicInteger classe méthodes communes:
De AtomicInteger ( int le initialValue): Crée une nouvelle valeur initiale avec la donnée AtomicIntegeraddAddGet ( int Dalta): Valeur atomiquement donnée et la valeur actuelle est ajoutée get (): Obtenez la valeur actuelle
Exemples de code:
changement basé sur la seule banque le code restant avec le premier exemple ci-dessus
class Banque { privée compte AtomicInteger = nouveau AtomicInteger (100 );
publique AtomicInteger getAccount () { retour compte; }
Publique vide save ( int argent) { account.addAndGet (argent); } }