//Exemple NG
public class SynchronizedNotUse {
//Données partagées par plusieurs threads
private int value = 0;
//Exécuter 100 000 threads
public static void main(String[] args) {
final int TASK_NUM = 100000;
var th = new Thread[TASK_NUM];
var tb = new SynchronizedNotUse();
//Création et exécution de threads
for (var i = 0; i < TASK_NUM; i++) {
th[i] = new Thread(() -> {
tb.increment();
});
th[i].start();
}
//Attendez la fin du fil
for (var i = 0; i < TASK_NUM; i++) {
try {
th[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(tb.value); //Différent à chaque fois
}
//Incrémenter le champ de valeur
void increment() {
this.value++;
}
}
public class SynchronizedUse {
private int value = 0;
public static void main(String[] args) {
final int TASK_NUM = 100000;
var th = new Thread[TASK_NUM];
var tb = new SynchronizedUse();
for (var i = 0; i < TASK_NUM; i++) {
th[i] = new Thread(() -> {
tb.increment();
});
th[i].start();
}
for (var i = 0; i < TASK_NUM; i++) {
try {
th[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(tb.value);
}
//Spécifiez l'objet à verrouiller comme instance actuelle
void increment() {
synchronized(this) {
this.value++;
}
}
}
volatile
peut également être utilisé uniquement pour l'affectation / la récupération de variablessynchronized void increment() {
this.value++;
}
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockBasic {
private int value = 0;
private final Lock lock = new ReentrantLock();
public static void main(String[] args) {
final int TASK_NUM = 100000;
var th = new Thread[TASK_NUM];
var tb = new LockBasic();
for (var i = 0; i < TASK_NUM; i++) {
th[i] = new Thread(() -> {
tb.increment();
});
th[i].start();
}
for (var i = 0; i < TASK_NUM; i++) {
try {
th[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(tb.value);
}
void increment() {
//Verrouiller l'acquisition
lock.lock();
try {
this.value++;
} finally {
//ouvrir
lock.unlock();
}
}
}
if (lock.tryLock(10,TimeUnit.SECONDS)) {
try {
//Traitement qui devrait être contrôlé exclusivement
} finally {
lock.unlock();
}
}else{
//Que faire si vous ne pouvez pas obtenir de cadenas
}
synchronized
et java.util.concurrent.locks
sont des contrôles exclusifs qui supposent des verrous.import java.util.concurrent.atomic.AtomicInteger;
public class AtomicBasic {
private AtomicInteger value = new AtomicInteger();
public static void main(String[] args) {
final int TASK_NUM = 100000;
var th = new Thread[TASK_NUM];
var tb = new AtomicBasic();
for (var i = 0; i < TASK_NUM; i++) {
th[i] = new Thread(() -> {
tb.increment();
});
th[i].start();
}
for (var i = 0; i < TASK_NUM; i++) {
try {
th[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(tb.value);
}
void increment() {
value.getAndIncrement();
}
}
public class ThreadPool implements Runnable {
@Override
public void run() {
for (var i = 0; i < 30; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
import java.util.concurrent.Executors;
public class ThreadPoolBasic {
public static void main(String[] args) {
//Générer un pool de threads avec 10 threads
var es = Executors.newFixedThreadPool(10);
//Appel et exécution avec la méthode d'exécution
es.execute(new ThreadPool());
es.execute(new ThreadPool());
es.execute(new ThreadPool());
es.shutdown();
}
}
import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ThreadSchedule {
public static void main(String[] args) {
//Préparation du pool de threads
var sche = Executors.newScheduledThreadPool(2);
//Enregistrement de l'exécution du calendrier
sche.scheduleAtFixedRate(() -> {
System.out.println(LocalDateTime.now());
}, 0, 5, TimeUnit.SECONDS);
//Suspendre le thread principal en attendant que le programme s'exécute
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Arrêtez le pool de threads
sche.shutdown();
}
}
//Trouvez un nombre aléatoire dans un autre thread et faites une pause pendant quelques millisecondes
//Afficher la valeur dans le thread principal
import java.util.Random;
import java.util.concurrent.Callable;
//Callable<Integer>Attribuer un type entier avec
public class ThreadCallable implements Callable<Integer> {
@Override
//Code à exécuter dans l'interface appelable
public Integer call() throws Exception {
var rnd = new Random();
var num = rnd.nextInt(1000);
Thread.sleep(num);
return num;
}
}
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
public class ThreadCallableBasic {
public static void main(String[] args) {
//Exécution de thread
var exe = Executors.newSingleThreadExecutor();
var r1 = exe.submit(new ThreadCallable());
var r2 = exe.submit(new ThreadCallable());
var r3 = exe.submit(new ThreadCallable());
//Affichage des résultats du fil
//La valeur de retour de la méthode d'envoi est Future<Integer>
try {
System.out.println("r1: " + r1.get());
System.out.println("r2: " + r2.get());
System.out.println("r3: " + r3.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
exe.shutdown();
}
}
//Trouvez un nombre aléatoire dans un autre thread et faites une pause pendant quelques millisecondes
//Montrez sa valeur
import java.util.Random;
import java.util.concurrent.CompletableFuture;
public class FutureBasic {
public static void main(String[] args) {
//Exécution du traitement asynchrone
CompletableFuture.supplyAsync(() -> {
var r = new Random();
var num = r.nextInt(1000);
heavy(num);
return num;
})
//Traitement après achèvement
.thenAcceptAsync((result) -> {
System.out.println(result);
});
System.out.println("...Tout post-traitement...");
heavy(7000);
}
//Le traitement factice (lourd) suspend le traitement uniquement pendant la durée spécifiée
public static void heavy(int num) {
try {
Thread.sleep(num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.Random;
import java.util.concurrent.CompletableFuture;
public class FutureComplete {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
var r = new Random();
var num = r.nextInt(1000);
heavy(num);
return num;
})
.whenCompleteAsync((result, ex) -> {
//Succès
if (ex == null) {
System.out.println(result);
} else {
//Échec
System.out.println(ex.getMessage());
}
});
heavy(7000);
}
public static void heavy(int num) {
try {
Thread.sleep(num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.Random;
import java.util.concurrent.CompletableFuture;
public class FutureSeq {
public static void main(String[] args) {
//Processus 1(Génération aléatoire)
CompletableFuture.supplyAsync(() -> {
var r = new Random();
var num = r.nextInt(5000);
heavy(2000);
System.out.printf("Processus 1: %d\n", num);
return num;
})
//Processus 2(Temps aléatoires)
.thenApplyAsync((data) -> {
var result = data * 2;
heavy(2000);
System.out.printf("Processus 2: %d\n", result);
return result;
})
//Processus 3(Double aléatoire)
.thenAcceptAsync((data) -> {
var num = data * 2;
heavy(2000);
System.out.printf("Processus 3: %d\n", num);
});
heavy(7000);
}
public static void heavy(int num) {
try {
Thread.sleep(num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Recommended Posts