Problèmes courants de sécurité des threads et solutions dans le développement Java
Dans le développement Java, le multithreading est un concept très courant et important. Cependant, le multithreading entraîne souvent une série de problèmes de sécurité des threads. Les problèmes de sécurité des threads font référence aux erreurs de données, aux erreurs logiques et à d'autres problèmes qui peuvent survenir lorsque plusieurs threads accèdent à des ressources partagées en même temps. Cet article présentera certains problèmes courants de sécurité des threads et fournira les solutions correspondantes, ainsi que des exemples de code.
Solution 1 : utilisez le mot-clé synchronisé
En utilisant le mot-clé synchronisé sur les segments de code clés, vous pouvez vous assurer qu'un seul thread peut exécuter le segment de code en même temps, évitant ainsi les problèmes de condition de concurrence.
Exemple de code :
class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } }
Solution 2 : Utiliser l'interface Lock
L'utilisation de l'interface Lock peut fournir un verrouillage plus fin Par rapport à la synchronisation, l'interface Lock est plus flexible.
Exemple de code :
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class Counter { private int count = 0; private Lock lock = new ReentrantLock(); public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); } } public int getCount() { return count; } }
Il existe deux manières principales d'éviter les blocages :
La première consiste à éviter les dépendances circulaires.
La seconde consiste à utiliser un pool de threads (ThreadPoolExecutor) au lieu de créer des threads individuellement. Le pool de threads peut gérer efficacement le cycle de vie des threads et. éviter les blocages.
Exemple de code :
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class Resource { private final Object lock1 = new Object(); private final Object lock2 = new Object(); public void methodA() { synchronized (lock1) { synchronized (lock2) { // do something } } } public void methodB() { synchronized (lock2) { synchronized (lock1) { // do something } } } } public class Main { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(2); Resource resource = new Resource(); executorService.submit(() -> resource.methodA()); executorService.submit(() -> resource.methodB()); executorService.shutdown(); } }
Solution : utilisez les méthodes wait() et notify() ensemble. La méthode wait() peut faire attendre le thread actuel et la méthode notify() peut réveiller un thread en attente.
class SharedResource { private int value; private boolean isValueSet = false; public synchronized void setValue(int value) { while (isValueSet) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.value = value; isValueSet = true; notify(); } public synchronized int getValue() { while (!isValueSet) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } isValueSet = false; notify(); return value; } } public class Main { public static void main(String[] args) { SharedResource sharedResource = new SharedResource(); Thread producer = new Thread(() -> { for (int i = 0; i < 10; i++) { sharedResource.setValue(i); System.out.println("Producer produces: " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread consumer = new Thread(() -> { for (int i = 0; i < 10; i++) { int value = sharedResource.getValue(); System.out.println("Consumer consumes: " + value); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); producer.start(); consumer.start(); } }
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!