1.关于JUC:
在 Java 5.0 提供了 java.util.concurrent (简称 JUC )包,在此包中增加了在并发编程中很常用 的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的 Collection 实现等。
2.volatile 关键字:内存可见性
内存可见性:是指当某个线程正在使用对象状态而另一个线程在同时修改该状态,需要确保当一个线程修改了对象状态后,其他线程能够看到发生的状态变化。
可见性错误是指当读操作与写操作在不同的线程中执行时,我们无法确保执行读操作的线程能适时de地看到其他线程写入的值,you有时甚至是跟本不可能的事。
我们可以通过同步来保证对象被安全的发布。除此之外我们也可以使用一种更加qing轻量级的volatile变量。
volatile:java提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。ke’y可以将volatile看作一个轻量级的锁,但是又与锁有些不同: a.对于多线程,不是一种互斥关系; b.不能保证变量状态的原子性操作。
一个volatile案例:如果变量flag不用volatile修饰则结果为:flag=true;
如果变量flag用volatile修饰则结果为:flag=true
—————;
因为volatile 保证了内存可见性,此时main方法中的主线程识别出flag为true所以会执行打印的代码。
public class TestVolatile {
public static void main(String[] args) {
Demo demo = new Demo();
new Thread(demo).start();
while(true){
//synchronized(demo){
if(demo.isFlag()){
System.out.println("---------------");
break;
}
//}
}
}
}
class Demo implements Runnable{
private volatile boolean flag =false;
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;
}
}
3.原子变量 CAS算法
引子:i++ 的原子性问题:i++ 的操作实际上分为三个步骤“读-改-写”
int i = 10;
i = i++; //10
int temp = i;temp为内存的值
i = i + 1;
i = temp;
当执行一个原子性操作的时候,有的时候会读到没有经过计算的内存值,即i=i++=10.这时就需要研究这个操作的yuan原子性
3.1CAS算法:
CAS(Compare-And-Swap)是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊的指令,用于管理dui’对贡献数据的并发fan访问。
CAS是一种无锁的非阻塞suan算法的实现;
CAS包含三个操作:
需要读写的内存值V
需要比较的值A
拟写入的新值B
当且仅当V的值等于A的值时,CAS通过原子方式用新值B来更新V的值,否则不会执行ren’任何操作。
两个Demo:
public class TestAtomicDemo {
public static void main(String[] args) {
//常规的int变量实现累加,结果有重复,没有保证线程安全
//有重复的现象出现,出现的原因就是这个操作分为三步,即读,改,写;在执行这三步操作的时
//候,没有保证一致性(原子性)提前读取了数据,之后导致重复数据的出现.
//结果:0013256478
AtmoicDemo ad = new AtmoicDemo();
for(int i=0;i<10;i++){
new Thread(ad).start();
}
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//原子变量实现的,结果没有重复的数字,实现了CAS的原子性
//结果:1203475986
AtmoicDemo2 ad2 = new AtmoicDemo2();
for(int i =0;i<10;i++){
new Thread(ad2).start();
}
}
}
class AtmoicDemo implements Runnable{
private int seriaNumber;
public void run() {
try {
Thread.currentThread().sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("1:"+seriaNumber++);
}
}
class AtmoicDemo2 implements Runnable{
private AtomicInteger serNum = new AtomicInteger();
public void run() {
try {
Thread.currentThread().sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("2:"+getSerNUm());
}
public int getSerNUm(){
return serNum.getAndIncrement();
}
}