No es difícil ejecutar un programa; ¡lo difícil es qué tan lejos puede ejecutarse el programa! —— una semilla feroz
Serie de concurrencia JUC
1. ¿Qué es la condición?
La condición se actualizó en jdk1.5, que se puede usar para reemplazar la espera y notificación original para lograr la cooperación entre subprocesos, porque los métodos de espera y señal de condición son más seguros y eficientes.
Puede ver la serie anterior de múltiples subprocesos en profundidad. Utilizamos el método de monitorización y el método de semáforo para resolver el problema de productores y consumidores mediante esperar y notificar .
2. Código de tipo de mano para lograr la condición para lograr una activación de notificación precisa
Hay un escenario en el que queremos que se ejecute un resultado de salida en el orden de ABC, luego usamos la Condición protagonista de hoy para lograrlo.
2.1 La condición no se usa
Antes de implementar la condición para notificar con precisión la activación, primero observe el segmento de código que no usa la condición para generar el resultado. (Comparar el aprendizaje es más intuitivo)
public class demo{
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 5; i++) {
data.testA();
}
},"一颗剽悍的种子A").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
data.testB();
}
},"一颗剽悍的种子B").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
data.testC();
}
},"一颗剽悍的种子C").start();
}
}
class Data{
public void testA(){
System.out.println(Thread.currentThread().getName() + "A");
}
public void testB(){
System.out.println(Thread.currentThread().getName() + "B");
}
public void testC(){
System.out.println(Thread.currentThread().getName() + "C");
}
}
resultado de la operación
Puede ver que el orden está desordenado, no en el orden de ejecución que queremos.
2.2 Condición de uso para lograr una activación de notificación precisa
Synchronized es una cerradura exclusiva, el proceso de bloqueo y desbloqueo se realiza automáticamente, lo que es fácil de operar, pero no lo suficientemente flexible. ReentrantLock también es una cerradura exclusiva, pero el proceso de bloqueo y desbloqueo debe realizarse manualmente, lo cual no es fácil de operar, pero sí muy flexible.
Clave
Bloqueo manual -> Juicio -> Ejecución -> Notificación -> Bloqueo manual
public void testA(){
lock.lock();
try {
while (num != 1){
conditionA.await(); //等待
}
System.out.println(Thread.currentThread().getName() + "A");
num++;
conditionB.signal(); //通知
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
Todos los códigos
public class demo{
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (Integer i = 0; i < 5; i++) {
data.testA();
}
},"一颗剽悍的种子A").start();
new Thread(()->{
for (Integer i = 0; i < 5; i++) {
data.testB();
}
},"一颗剽悍的种子B").start();
new Thread(()->{
for (Integer i = 0; i < 5; i++) {
data.testC();
}
},"一颗剽悍的种子C").start();
}
}
class Data{
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private Condition conditionC = lock.newCondition();
private Integer num = 1; //1 = A 2 = B 3 = C
public void testA(){
lock.lock();
try {
while (num != 1){
conditionA.await(); //等待
}
System.out.println(Thread.currentThread().getName() + "A");
num++;
conditionB.signal(); //通知
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void testB(){
lock.lock();
try {
while (num != 2){
conditionB.await(); //等待
}
System.out.println(Thread.currentThread().getName() + "B");
num++;
conditionC.signal(); //通知
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void testC(){
lock.lock();
try {
while (num != 3){
conditionC.await(); //等待
}
System.out.println(Thread.currentThread().getName() + "C");
num = 1;
conditionA.signal(); //通知
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
resultado de la operación
3. Evite los despertares falsos
Si ha visto la serie anterior de múltiples subprocesos en profundidad o el código anterior, si presta atención, encontrará que usamos el juicio while más que si en el juicio , porque si puede haber falsas activaciones.
Entonces, ¿qué es para prevenir despertares falsos?
El llamado falso despertar significa que aunque el hilo puede despertarse, no será notificado, interrumpido o agotado.
Cuatro, finalmente
Al final, para una mejor experiencia de lectura, pongo todo lo que quiero decir a continuación, jeje.
Soy semilla de decisiones basadas en mi voluntad, en serio compartir lo que escribí en el blog ha sido el mismo credo.
Si puedes leer esta entrada del blog, significa que todavía estamos muy destinados; espero que te pueda traer algo de ayuda, la creación no es fácil, quita el conocimiento de mi artículo, tus tres seguidos dejan, me gusta, comenta, sigue , Es mi mayor motivación.