#####内存可见性问题
当多个线程操作共享数据时,彼此不可见
Volatile 关键字: 保证多个线程进行操作共享数据时,可以保证内存中数据可见
- 1.Volatile 不具有互斥性;
- 2.Volatile 不能保证变量的原子性
package com.diedline.juc;
/**
* 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;
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = true;
System.out.println("flag = " + isFlag());
}
}
####CAS算法 和原子变量的使用
在这个包下查询 使用原子变量能解决内存可见性的问题和原子性的问题并且效率比同步锁要高
java.util,concurrent.atomic
package com.diedline.juc;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 一. i++的原子性问题 i++ 的操作实际分为三个步骤“读,改,写”
* int i =10;
* i = i++; //10
*
* 底层
* int temp=i;
* i = i + 1;
* i = temp;
*
*
* 二: 原子变量: jdk 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 atd = new ATomicDemo();
for (int i = 0; i < 10; i++) {
new Thread(atd).start();
}
}
}
class ATomicDemo implements Runnable{
//使用原子变量 跟Integer 这种包装类很相像
private AtomicInteger serialNumber = new AtomicInteger();
public int getSerialNumber() {
return serialNumber.getAndIncrement();
}
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( getSerialNumber());
}
}
#####模拟CAS算法
package com.diedline.juc;
public class TestCompareAndSwap {
/**
* 模拟CAS算法
*
* @param args
*/
public static void main(String[] args) {
final CompareAndSwap cas = new CompareAndSwap();
for (int i = 0; i <10 ; i++) {
new Thread(
new Runnable() {
@Override
public void run() {
int expectedValue = cas.get();
boolean b = cas.compareAndSet(expectedValue,(int)(Math.random()*101));
System.out.println(b);
}
}
).start();
}
}
}
class CompareAndSwap{
private int value;
//获取内存值
public synchronized int get(){
return value;
}
//比较
public synchronized int compareAndSwap(int expectValue,int newValue){
int oldValue = value;
if(oldValue == expectValue){
this.value = newValue;
}
return oldValue;
}
//设置值
public synchronized boolean compareAndSet(int expectedValue, int newValue){
return expectedValue ==compareAndSwap(expectedValue,newValue);
}
}