线程安全的实现方法(2)---非阻塞同步

上文说到了线程安全的互斥同步实现方法,这里说一下非阻塞同步。

非阻塞同步

互斥同步的主要问题是线程阻塞和唤醒所带来的性能问题,所以互斥同步也叫阻塞同步。

说到底,互斥同步是一种悲观锁,悲观锁优势是简单,劣势是性能差;相对应的就是乐观锁,简单来说:先进行操作,如果没有其他线程争用共享数据,那操作就成功了,如果有争用,产生了冲突,再采取补救。这种方式不需要把线程挂起,所以是非阻塞的。

乐观锁的优势是减少了锁建立和释放的次数,劣势是需要“硬件指令集的发展”。因为我们需要对操作和冲突检测另个步骤都具备原子性,这里只能靠硬件来完成。

典型的乐观锁比如CAS,以下是使用CAS操作来避免阻塞同步的一个例子:代码的逻辑很简单,即进行20个自增10000此的操作。

import java.util.concurrent.atomic.AtomicInteger;

public class CASTest{
    public static AtomicInteger race = new AtomicInteger(0);
    public static void increase(){
        race.incrementAndGet();
    }
    public static final int THREAD_COUNT = 20;
    public static void main(String[] args) {
        Thread [] threads = new Thread[THREAD_COUNT];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new Runnable(){

                @Override
                public void run() {
                    for (int j = 0; j < 10000; j++) {
                        increase();
                    }
                }
                
            });
            threads[i].start();
        }
        while(Thread.activeCount()>1){
            Thread.yield();
        }
        System.out.println(race);
    }
}

程序中使用AtomicInteger代替int,程序输出稳定为200000,这要归功于incrementAndGet()方法的原子性。源码如下:

public final int incrementAndGet(){
        for(;;){
            int current = get();
            int next = current +1;
            if(compareAndSet(current, next))
                return next;
        }
    }

你可能感兴趣的:(线程安全的实现方法(2)---非阻塞同步)