La copie de code est la suivante:
Package com.yao;
Importer java.util.concurrent.executorService;
Importer java.util.concurrent.executors;
import java.util.concurrent.future;
import java.util.concurrent.locks.lock;
import java.util.concurrent.locks.readwritelock;
Importer java.util.concurrent.locks.rentrantlock;
Importer java.util.concurrent.locks.RentranTreadWriteLock;
/ **
* Casiers
* Un concept important dans la programmation multi-thread est le verrouillage.
* Lorsque vous effectuez des opérations transactionnelles, la ressource partagée doit être verrouillée, ce qui garantit qu'un seul thread peut fonctionner sur la ressource lors de l'exécution des opérations transactionnelles.
* Cela garantit l'intégrité des données. Avant 5.0, la fonction de verrouillage a été implémentée par le mot clé synchronisé.
* /
Lockers de classe publique {
/ **
* Testez l'utilisation du verrouillage. L'utilisation de verrouillage dans la méthode peut éviter d'utiliser le mot-clé synchronisé.
* /
classe statique publique Locktest {
Verrouillage de verrouillage = new rentrantLock (); // verrouillage
Double valeur = 0d;
int compdtimes = 0;
/ **
* Augmentez la valeur de la valeur.
* Ainsi, la méthode doit être synchronisée, la pratique précédente était d'utiliser le mot-clé synchronisé dans la déclaration de la méthode.
* /
public void addValue (double v) {
lock.lock (); // Obtenez le verrouillage
System.out.println ("Locktest à AddValue:" + V + ""
+ System.Currenttimemillis ());
essayer {
Thread.Sleep (1000);
} catch (InterruptedException e) {
}
this.value + = v;
this.addtimes ++;
lock.unlock (); // relâchez le verrouillage
}
public double getValue () {
Renvoyez cette valeur;
}
}
public static void testlockTest () lève une exception {
Final LockTest LockTest = new LockTest ();
// Créez une nouvelle tâche 1 et appelez la méthode AddValue de Locktest
Runnable task1 = new runnable () {
public void run () {
locktest.addvalue (55,55);
}
};
// Créez une nouvelle tâche 2 et appelez la méthode GetValue de Locktest
Runnable task2 = new runnable () {
public void run () {
System.out.println ("Valeur:" + LockTest.GetValue ());
}
};
// Créer un nouveau service d'exécution de tâches
ExecutorService cachedService = exécutors.newcachedThreadPool ();
Futur futur = null;
// Exécuter la tâche 1 trois fois en même temps.
pour (int i = 0; i <3; i ++) {
futur = cachedService.Submit (tâche1);
}
// attendez que la dernière tâche 1 soit exécutée
futur.get ();
// exécuter à nouveau la tâche 2 pour sortir le résultat
futur = cachedService.Submit (tâche2);
// Après avoir attendu l'exécution de la tâche 2, fermez le service d'exécution de la tâche
futur.get ();
cachedService.shutdownNow ();
}
/ **
* ReadWriteLock a deux verrous intégrés, l'un est le verrou de lecture et l'autre est le verrou écrit.
* Plusieurs threads peuvent obtenir des verrous en lecture en même temps, mais un seul thread peut obtenir des verrous écrits.
* Et après verrouillage du verrouillage écrit, aucun fil ne peut obtenir le verrou. Les méthodes fournies par ReadWriteLock sont:
* readlock (): renvoie un verrou de lecture
* writeLock (): Renvoie un verrou écrit, ce verrou est exclusif.
* ReadWriteLocktest convient très bien à la gestion des opérations de lecture et d'écriture de fichiers similaires.
* Vous pouvez lire en même temps lors de la lecture, mais vous ne pouvez pas écrire; vous ne pouvez pas écrire en même temps ou lire en même temps lors de l'écriture.
* /
classe statique publique ReadWriteLocktest {
// Verrouillage
LEADWRITELOCK LOCK = NOUVEAU REENTRANTREADWRITELOCK ();
// Valeur
double valeur = 0d;
int compdtimes = 0;
/ **
* Augmentez la valeur de la valeur et ne permettez pas à plusieurs threads d'entrer la méthode en même temps.
* /
public void addValue (double v) {
// Obtenez WriteLock et Lock
Lock WriteLock = Lock.WriteLock ();
writeLock.lock ();
System.out.println ("readWriteLocktest to AddValue:" + V + ""
+ System.Currenttimemillis ());
essayer {
Thread.Sleep (1000);
} catch (InterruptedException e) {
}
essayer {
// fait le travail d'écriture
this.value + = v;
this.addtimes ++;
} enfin {
// Libérez le verrou d'écriture
writeLock.unlock ();
}
}
/ **
* Obtenez des informations. Lorsqu'un thread appelle la méthode AddValue, les informations obtenues par GetInfo peuvent être incorrectes.
* Par conséquent, il est également nécessaire de s'assurer que lorsque la méthode est appelée, aucune méthode n'appelle la méthode AddValue.
* /
String public getInfo () {
// Obtenez la lecture et le verrouillage
Lock ReadLock = Lock.Readlock ();
readlock.lock ();
System.out.println ("readWriteLocktest to GetInfo"
+ System.Currenttimemillis ());
essayer {
Thread.Sleep (1000);
} catch (InterruptedException e) {
}
essayer {
// fait le travail de lecture
Renvoie ce.value + ":" + this.addtimes;
} enfin {
// Libérez Readlock
readlock.unlock ();
}
}
}
public static void testReadWriteLockTest () lève une exception {
Final readWriteLockTest readWriteLockTest = new ReadWriteLockTest ();
// Créez une nouvelle tâche 1 et appelez la méthode AddValue de Locktest
Runnable task_1 = new runnable () {
public void run () {
readWriteLocktest.AddValue (55,55);
}
};
// Créez une nouvelle tâche 2 et appelez la méthode GetValue de Locktest
Runnable task_2 = new runnable () {
public void run () {
System.out.println ("info:" + readWriteLocktest.getInfo ());
}
};
// Créer un nouveau service d'exécution de tâches
ExecutorService cachedService_1 = exécutors.newcachedThreadPool ();
Futur future_1 = null;
// Exécuter 5 tâches en même temps, dont les 2 premières tâches sont Task_1 et les deux dernières tâches sont Task_2
pour (int i = 0; i <2; i ++) {
futur_1 = cachedService_1.Submit (task_1);
}
pour (int i = 0; i <2; i ++) {
futur_1 = cachedService_1.submit (task_2);
}
// La dernière tâche est Task_1
futur_1 = cachedService_1.Submit (task_1);
// L'ordre d'exécution de ces 5 tâches devrait être:
// La première tâche_1 est exécutée en premier, et la deuxième tâche_1 est exécutée à nouveau;
// Ensuite, deux tâches_2 sont exécutées en même temps;
// parce qu'ils peuvent être lus en même temps, ils sont exécutés en même temps
// La dernière tâche_1 est à nouveau exécutée. En effet, vous ne pouvez pas écrire lors de la lecture, vous devez donc attendre la fin de la lecture avant de pouvoir écrire.
// attendez que la dernière tâche_2 soit exécutée
futur_1.get ();
cachedService_1.shutdownNow ();
}
public static void main (String [] args) lève une exception {
Lockers.TestLockTest ();
System.out.println ("---------------------");
Lockers.TestReadWriteLockTest ();
}
}