Le but de la vie est de se développer, l'essence de la vie est au changement, le défi de la vie est de conquérir
le but de la vie est de se développer, l'essence de la vie est le changement, le défi de la vie est de conquérir
Le mot clé synchronized est presque une question obligatoire pour chaque entretien. Aujourd'hui, parlons de l'utilisation de synchronized et de ses scénarios d'utilisation.
Comme nous le savons tous, il existe trois caractéristiques principales dans le modèle de mémoire Java, l' atomicité, la visibilité et l'ordre
synchronisé: garantit visibilité et atomicité
Dans le modèle de mémoire Java, synchronized stipule que lorsqu'un thread est verrouillé, il efface d'abord la mémoire de travail-> copie la dernière copie de variable de la mémoire principale dans la mémoire de travail-> exécute le code-> modifie les variables partagées La valeur est rafraîchie dans la mémoire principale-> relâchez le mutex
Ordre: l'ordre naturel dans un programme Java peut être résumé en une phrase. Si vous observez dans ce fil, toutes les opérations sont naturellement ordonnées, et si vous observez un autre fil dans un fil, toutes les opérations sont hors service. De
Et regardez le mode singleton avec double verrouillage ci-dessous
private volatile static Singleton singleton;
public static Singleton getSingleton(){
if(null == singleton){
synchronized (Singleton.class) {
if(null == singleton){
singleton = new Singleton();
}
}
}
return singleton;
}
public static void main(String[] args) {
for(int i = 0;i<10;i++){
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+Singleton.getSingleton().hashCode());
}}).start();
}复制代码
Comme vous pouvez le voir, l'objet Singleton a été modifié avec volatile, et il a été jugé à nouveau deux fois. La visibilité modifiée a été implémentée avec modification volatile (volatile est également un mot-clé). Les deux jugements sont parce que le premier jugement a été Le mode singleton n'a besoin que de créer une instance, et s'il est appelé à nouveau plus tard, il reviendra directement à l'instance précédemment créée, donc la plupart du temps, il n'est pas nécessaire d'exécuter le code dans la méthode de synchronisation, ce qui améliore considérablement les performances. Le deuxième jugement est que l'on suppose qu'après l'exécution de la première vérification par le thread 1, le thread 2 acquiert également les droits d'exécution de l'unité centrale de traitement. Ensuite, le thread 2 acquiert un verrou et crée une instance. À ce stade, le thread 1 obtient le droit d'exécution et crée également une instance. Par conséquent, plusieurs instances seront créées , vous devez donc effectuer une deuxième vérification dans le code de synchronisation. Si l'instance est vide, recréez-la de sorte qu'un seul objet soit créé.
synchronisé peut être ajouté à la méthode peut également être ajouté au bloc de code
class Sync{
public synchronized void test() {
System.out.println("test开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test结束..");
}
}
class MyThread extends Thread {
public void run() {
Sync sync = new Sync();
sync.test();
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread thread = new MyThread();
thread.start();
}
}
}
} 复制代码
Résultat de l'opération:
Il n'y a pas eu de changement et je n'ai pas vu la synchronisation jouer un rôle
Ensuite, nous essayons d'ajouter synchronisé au bloc de code pour réduire la granularité du verrou
class Sync {
public void test() {
synchronized (Sync.class) {
System.out.println("test开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test结束..");
}
}
}
class MyThread extends Thread {
public void run() {
Sync sync = new Sync();
sync.test();
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread thread = new MyThread();
thread.start();
}
}
} 复制代码
运行结果:
test开始.. test结束.. test开始.. test结束.. test开始.. test结束..复制代码
On peut voir que le verrou synchronisé n'est pas cela, mais l'objet Class Class
Réentrance synchronisée
Résumé
Le verrou synchronisé est soit une instance de la classe, soit l'objet transmis, ou cette phrase, synchronisé de sorte que les variables ou les blocs de code ne sont accessibles que par un thread à la fois