1. 无锁类的原理详解
CAS算法
CAS算法的过程是这样:它包含3个参数CAS(V,E,N)。V表示要更新的变量,E表示预期值,N表示新值。仅当V 值等于E值时,才会将V的值设为N,如果V值和E值不同,则说明已经有其他线程做了更新,则当前线程什么 都不做。最后,CAS返回当前V的真实值。CAS操作是抱着乐观的态度进行的,它总是认为自己可以成功完成 操作。当多个线程同时使用CAS操作一个变量时,只有一个会胜出,并成功更新,其余均会失败。失败的线程 不会被挂起,仅是被告知失败,并且允许再次尝试,当然也允许失败的线程放弃操作。基于这样的原理,CAS操作即时没有锁,也可以发现其他线程对当前线程的干扰,并进行恰当的处理。
2. 无锁类的使用
1.AtomicInteger
他是继承Number类
1 import java.util.concurrent.atomic.AtomicInteger; 2 3 public class AtomicIntegerTest { 4 static AtomicInteger i = new AtomicInteger(); 5 6 public static class AtomicIntegerThread implements Runnable{ 7 8 @Override 9 public void run() { 10 for(int k=0;k<10000;k++){ 11 //当前值加1,返回新值 12 i.incrementAndGet(); 13 } 14 } 15 } 16 17 public static void main(String[] args) throws InterruptedException{ 18 Thread [] ts = new Thread[10]; 19 for (int n = 0; n<10; n++){ 20 ts[n] = new Thread(new AtomicIntegerThread()); 21 } 22 for(int m=0; m<10;m++){ 23 ts[m].start(); 24 } 25 for(int m=0; m<10;m++){ 26 ts[m].join(); 27 } 28 System.out.println(i); 29 } 30 }
2.AtomicReference
对引用进行修改
是一个模板类,抽象化了数据类型
1 import java.util.concurrent.atomic.AtomicReference; 2 3 public class AtomicReferenceTest { 4 static AtomicReference<String> atomicStr = new AtomicReference<String>("wangxb"); 5 6 public static void main(String[] args) { 7 for(int i=0;i<10;i++){ 8 new Thread(new Runnable() { 9 @Override 10 public void run() { 11 try { 12 Thread.sleep(Math.abs((int)(Math.random()*100))); 13 }catch (InterruptedException e){ 14 e.printStackTrace(); 15 } 16 /** 17 * Atomically sets the value to the given updated value 18 * if the current value {@code ==} the expected value.*/ 19 if(atomicStr.compareAndSet("wangxb","zbbiex")){ 20 System.out.println("Thread: "+Thread.currentThread().getId()+" change atomic value"); 21 }else{ 22 System.out.println("Thread: "+Thread.currentThread().getId()+" is FAILED"); 23 } 24 } 25 }).start(); 26 } 27 } 28 }
3.AtomicIntegerArray
支持无锁的数组
1 import java.util.concurrent.atomic.AtomicIntegerArray; 2 3 public class AtomicIntegerArrayTest { 4 static AtomicIntegerArray arr = new AtomicIntegerArray(10); 5 public static class AtomicIntegerArrayThread implements Runnable{ 6 7 @Override 8 public void run() { 9 for (int i=0;i<10000;i++){ 10 arr.getAndIncrement(i%arr.length()); 11 } 12 } 13 } 14 15 public static void main(String[] args) throws InterruptedException{ 16 Thread [] ts = new Thread[10]; 17 for (int n = 0; n<10; n++){ 18 ts[n] = new Thread(new AtomicIntegerArrayThread()); 19 } 20 for(int k=0; k<10;k++){ 21 ts[k].start(); 22 } 23 for(int k=0; k<10;k++){ 24 ts[k].join(); 25 } 26 System.out.println(arr); 27 } 28 29 }
4.AtomicIntegerFieldUpdater
让普通变量也享受原子操
1 public class AtomicFieldUpdaterTest { 2 public static class Student{ 3 int i = 0; 4 volatile int score; 5 } 6 public final static AtomicIntegerFieldUpdater scoreUpdater = AtomicIntegerFieldUpdater.newUpdater(Student.class,"score"); 7 static AtomicInteger allScore = new AtomicInteger(0); 8 9 public static void main(String[] args) throws InterruptedException{ 10 final Student stu = new Student(); 11 Thread[] ts = new Thread[10000]; 12 for(int i = 0; i < 10000; i++){ 13 ts[i] = new Thread(){ 14 public void run(){ 15 if(Math.random()>0.4){ 16 scoreUpdater.incrementAndGet(stu); 17 allScore.incrementAndGet(); 18 } 19 } 20 }; 21 ts[i].start(); 22 } 23 for(int i = 0; i < 10000; i++){ 24 ts[i].join(); 25 } 26 System.out.println("score: "+ stu.score); 27 System.out.println("allScore: "+ allScore); 28 29 } 30 }