Maison  >  Article  >  Java  >  Qu'est-ce qui est synchronisé ? Comment utiliser la synchronisation ?

Qu'est-ce qui est synchronisé ? Comment utiliser la synchronisation ?

PHP中文网
PHP中文网original
2017-06-21 13:27:182318parcourir

synchronisé

Avant-propos

Je crois que tout le monde a entendu parler des problèmes de sécurité des threads lors de l'apprentissage des systèmes d'exploitation, un point de connaissance est les ressources critiques. Pour le dire simplement, seulement une ressource. cela permet à un processus de fonctionner, mais lorsque nous utilisons le multithreading, nous opérons simultanément et nous ne pouvons pas contrôler l'accès et la modification d'une seule ressource en même temps. Nous voulons contrôler plusieurs opérations aujourd'hui. à propos de la deuxième méthode One : Bloc de synchronisation de thread ou méthode de synchronisation de thread (synchronisée)

Instance

  1. Ce qui suit est un exemple pour illustrer le synchronized mot-clé Utilisez la

méthode de synchronisation des threads

public class Sychor {public void insert(Thread thread) {for (int i = 0; i < 10; i++) {
            System.out.println(thread.getName() + "输出:  " + i);
        }

    }public static void main(String[] args) {final Sychor sychor = new Sychor();

        Thread t1 = new Thread() {public void run() {
                sychor.insert(Thread.currentThread());
            };
        };

        Thread t2 = new Thread() {public void run() {
                sychor.insert(Thread.currentThread());
            };
        };

        t1.start();
        t2.start();
    }
}

où le résultat de sortie est comme indiqué ci-dessous

Quest-ce qui est synchronisé ? Comment utiliser la synchronisation ?

D'après les résultats ci-dessus, nous pouvons voir que les deux threads ici exécutent la méthode insert() en même temps. Ajoutons le synchronized. mot-clé au code original pour voir Quel est l'effet ? Le code est le suivant :

public class Sychor {public synchronized void insert(Thread thread) {for (int i = 0; i < 10; i++) {
            System.out.println(thread.getName() + "输出:  " + i);
        }

    }public static void main(String[] args) {final Sychor sychor = new Sychor();

        Thread t1 = new Thread() {public void run() {
                sychor.insert(Thread.currentThread());
            };
        };

        Thread t2 = new Thread() {public void run() {
                sychor.insert(Thread.currentThread());
            };
        };

        t1.start();
        t2.start();
    }
}

Je ne listerai pas les résultats en cours du programme ci-dessus. Vous pouvez l'essayer vous-même. En bref, j'ai ajouté synchronizedLe mot-clé provoque l'exécution des threads un par un. Ce n'est que lorsqu'un thread est exécuté en premier qu'un autre thread peut être exécuté.

Bloc de synchronisation des threads

Bien sûr, nous utilisons la méthode de synchronisation des threads ci-dessus, nous pouvons utiliser le bloc de synchronisation des threads, ces deux-là sont plus flexibles que le bloc de synchronisation des threads, il suffit de le mettre le code qui doit être synchronisé dans le bloc de synchronisation, le code est le suivant

public class Sychor {public void insert(Thread thread) {synchronized (this) {for (int i = 0; i < 10; i++) {
                System.out.println(thread.getName() + "输出:  " + i);
            }
            
        }
        

    }public static void main(String[] args) {final Sychor sychor = new Sychor();

        Thread t1 = new Thread() {public void run() {
                sychor.insert(Thread.currentThread());
            };
        };

        Thread t2 = new Thread() {public void run() {
                sychor.insert(Thread.currentThread());
            };
        };

        t1.start();
        t2.start();
    }
}

Vous pouvez voir cette méthode à partir du code ci-dessus Plus flexible ; , il vous suffit de mettre les méthodes de code qui doivent être synchronisées dans le bloc de synchronisation, et le code qui n'a pas besoin d'être synchronisé à l'extérieur

Raisons détaillées

  1. Nous savons que chaque objet a un verrou Lorsque nous utilisons la méthode de synchronisation des threads ou le bloc de synchronisation des threads, nous obtenons en fait le seul verrou pour l'objet. , Ensuite, les autres threads ne peuvent être exclus que si nous disons ici qu'il s'agit d'un objet, ce qui signifie que c'est le même objet. S'il s'agit d'un objet différent, cela ne fonctionnera pas car différents objets ont des verrous d'objet différents. nous modifions le programme ci-dessus comme suit :

public class Sychor {public void insert(Thread thread) {synchronized (this) {for (int i = 0; i < 10; i++) {
                System.out.println(thread.getName() + "输出:  " + i);
            }
        }

    }public static void main(String[] args) {//第一个线程Thread t1 = new Thread() {public void run() {
                Sychor sychor = new Sychor();   //在run() 方法中创建一个对象sychor.insert(Thread.currentThread());
            };
        };//第二个线程Thread t2 = new Thread() {public void run() {
                Sychor sychor = new Sychor();  //创建另外的一个对象sychor.insert(Thread.currentThread());
            };
        };

        t1.start();
        t2.start();
    }
}

Il ressort des résultats ci-dessus que le bloc de synchronisation des threads fait n'existe pas du tout pour le moment. Cela fonctionne, car ils appellent la méthode d'insertion de différents objets, et l'obtention du verrou est différente

  1. Nous l'avons déjà dit ci-dessus. L'objet a un verrou. Les méthodes de synchronisation des threads et les blocs de synchronisation des threads obtiennent en fait le verrou de l'objet. Par conséquent, les parenthèses du bloc de synchronisation des threads sont remplies de

    . this dans une classe this

  1. Une classe a également un verrou unique Ce que nous avons dit plus tôt était. pour utiliser un objet pour appeler des méthodes membres. Maintenant, si nous appelons des méthodes statiques dans une classe, nous pouvons utiliser des méthodes de synchronisation de threads ou des blocs de synchronisation pour obtenir le seul verrou de la classe. Ensuite, nous pouvons contrôler plusieurs threads en appelant des méthodes statiques dans la classe. même classe en même temps. Le code est le suivant :

public class Sychor {// 静态方法public static synchronized void insert(Thread thread)  
    {for(int i=0;i<10;i++)
        {
            System.out.println(thread.getName()+"输出     "+i);
        }
    }public static void main(String[] args) {//第一个线程Thread t1 = new Thread() {public void run() {
                Sychor.insert(Thread.currentThread());  //直接使用类调用静态方法};
        };//第二个线程Thread t2 = new Thread() {public void run() {
                Sychor.insert(Thread.currentThread());   //直接使用类调用静态方法};
        };

        t1.start();
        t2.start();
    }
}
Remarque

  1. Pour assurer la sécurité des threads et le contrôle de la synchronisation, si vous exécutez une méthode non

    synchronisée ou un bloc synchronisé, vous devez utiliser le même objet si vous appelez une méthode synchronisée statique ou un bloc synchronisé. il, vous devez utiliser la même classe pour appeler static

  1. Si un thread accède à la méthode synchronisée

    et qu'un autre thread accède à la méthode synchronisée non statique, les deux ne le seront pas. Il y a un conflit car l'un est un verrou de classe et l'autre est un verrou d'objet static

  1. Si vous utilisez un bloc de synchronisation de thread, alors dans le bloc de synchronisation Le code est à accès contrôlé, mais le code extérieur est accessible à tous les threads

  1. Lors de l'exécution d'un bloc de code synchronisé Si une exception se produit dans le thread, alors

    libérera automatiquement le verrou occupé par le thread actuel, il n'y aura donc pas de blocage dû à des exceptions jvm

Article de référence


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn