Sección 2 visibilidad de la memoria de palabras clave volátiles

visibilidad de la memoria

  1. La visibilidad de la memoria (Memory Visibility) significa que cuando un subproceso está utilizando el estado del objeto y otro subproceso está modificando el estado al mismo tiempo, es necesario asegurarse de que cuando un subproceso modifica el estado del objeto, otros subprocesos pueden ver el cambio de estado que ocurre.
  2. Los errores de visibilidad significan que cuando las operaciones de lectura y las operaciones de escritura se realizan en diferentes subprocesos, no podemos garantizar que el subproceso que realiza la operación de lectura pueda ver los valores escritos por otros subprocesos de manera oportuna y, a veces, incluso es imposible.
  3. Podemos usar la sincronización para garantizar que los objetos se liberen de manera segura. Además, también podemos usar una variable volátil más ligera.

palabra clave volátil

Java proporciona un mecanismo de sincronización ligeramente más débil, a saber, variables volátiles, para garantizar que otros subprocesos sean notificados de las operaciones de actualización de variables. Volatile se puede considerar como un candado liviano, pero es algo diferente de los candados:
➢ Para subprocesos múltiples, no es una relación de exclusión mutua
➢ No se puede garantizar la "operación atómica" del estado variable

/*
 * 一、volatile 关键字:当多个线程进行操作共享数据时,可以保证内存中的数据可见。
 * 					  相较于 synchronized 是一种较为轻量级的同步策略。
 * 
 * 注意:
 * 1. volatile 不具备“互斥性”
 * 2. volatile 不能保证变量的“原子性”
 */
public class TestVolatile {
    
    
	
	public static void main(String[] args) {
    
    
		ThreadDemo td = new ThreadDemo();
		new Thread(td).start();
		
		while(true){
    
    
			if(td.isFlag()){
    
    
				System.out.println("------------------");
				break;
			}
		}
		
	}

}

class ThreadDemo implements Runnable {
    
    

	private volatile boolean flag = false;

	@Override
	public void run() {
    
    
		
		try {
    
    
			Thread.sleep(200);
		} catch (InterruptedException e) {
    
    
		}

		flag = true;
		
		System.out.println("flag=" + isFlag());

	}

	public boolean isFlag() {
    
    
		return flag;
	}

	public void setFlag(boolean flag) {
    
    
		this.flag = flag;
	}

}

Algoritmo CAS de variable atómica


CAS (Compare-And-Swap) es un soporte de hardware para la concurrencia, una instrucción especial en un procesador diseñado para la operación de múltiples procesadores y se utiliza para administrar el acceso simultáneo a los datos compartidos
.

  1. CAS es una implementación de un algoritmo sin bloqueo y sin bloqueo.
  2. CAS contiene 3 operandos:
    ➢ El valor de memoria V para leer y escribir ➢ El valor A para comparar ➢ El nuevo valor B para escribir
  3. Si y solo si el valor de V es igual a A, CAS actualiza atómicamente el valor de V con el nuevo valor B, de lo contrario no realiza ninguna operación

variable atómica

Un pequeño conjunto de herramientas de clases que admite programación segura para subprocesos que desbloquea un bloqueo en una sola variable. De hecho, las clases de este paquete
amplían el concepto de valores volátiles, campos y elementos de matriz a aquellos que también proporcionan operaciones de actualización condicional atómica.
⚫ Las instancias de las clases AtomicBoolean, AtomicInteger, AtomicLong y AtomicReference brindan
acceso y actualización a una única variable del tipo correspondiente. Cada clase también proporciona los métodos de utilidad apropiados para ese tipo.
⚫ Las clases AtomicIntegerArray, AtomicLongArray y AtomicReferenceArray amplían aún más las operaciones atómicas
para brindar compatibilidad con este tipo de matrices. Estas clases
también se destacan por proporcionar una semántica de acceso volátil para sus elementos de matriz, que no es compatible con las matrices normales.
⚫ Método principal: boolean compareAndSet(expectedValue, updateValue)
⚫ El paquete java.util.concurrent.atomic proporciona algunas clases comunes para operaciones atómicas:

  1. AtomicBoolean 、AtomicInteger 、AtomicLong 、 AtomicReference
  2. AtomicIntegerArray 、AtomicLongArray
  3. AtomicMarkableReference
  4. Matriz de referencia atómica
  5. AtomicStampedReference
import java.util.concurrent.atomic.AtomicInteger;

/*
 * 一、i++ 的原子性问题:i++ 的操作实际上分为三个步骤“读-改-写”
 * 		  int i = 10;
 * 		  i = i++; //10
 * 
 * 		  int temp = i;
 * 		  i = i + 1;
 * 		  i = temp;
 * 
 * 二、原子变量:在 java.util.concurrent.atomic 包下提供了一些原子变量。
 * 		1. volatile 保证内存可见性
 * 		2. CAS(Compare-And-Swap) 算法保证数据变量的原子性
 * 			CAS 算法是硬件对于并发操作的支持
 * 			CAS 包含了三个操作数:
 * 			①内存值  V
 * 			②预估值  A
 * 			③更新值  B
 * 			当且仅当 V == A 时, V = B; 否则,不会执行任何操作。
 */
public class TestAtomicDemo {
    
    

	public static void main(String[] args) {
    
    
		AtomicDemo ad = new AtomicDemo();
		
		for (int i = 0; i < 10; i++) {
    
    
			new Thread(ad).start();
		}
	}
	
}

class AtomicDemo implements Runnable{
    
    
	
//	private volatile int serialNumber = 0;
	
	private AtomicInteger serialNumber = new AtomicInteger(0);

	@Override
	public void run() {
    
    
		
		try {
    
    
			Thread.sleep(200);
		} catch (InterruptedException e) {
    
    
		}
		
		System.out.println(getSerialNumber());
	}
	
	public int getSerialNumber(){
    
    
		return serialNumber.getAndIncrement();
	}
	
	
}

Supongo que te gusta

Origin blog.csdn.net/m0_37294838/article/details/127683513
Recomendado
Clasificación