• lcok-free简易实现


    lock-free是一种基于原子变量类来构建的非阻塞同步算法。

    比较并交换(compare-and-swap)

    我们经常会先检查某项东西,然后对其进行修改,如if(X...) {X=...}。这种行为在多线程下并不是线程安全的。那我们该如何做呢?

    一种方法是对操作进行加锁,如

    synchornized(obj){

        if(x>0){

            x -=  10; 

        }

    }

    究其原因,是因为上面的操作是一个复合操作。我们是否可以通过某种不可分的方式来处理呢?...

    几乎所有的现代处理器都包含了比较并交换(CAS)指令。CAS包含了3个操作数--需要读写内存的位置V、进行比较的值A和拟写入的新值,当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不会执行任何操作。通过CAS我们可以把这种“先检查后执行”行为作为一个不可分的整体来处理。在Java1.5之后,原子变量类中提供了这种操作。

    下面写个简单取钱的例子,看看其在Java下的应用。账户有一定的余额(10000),在多线程下每个人一次可取4000。如果写的withDraw(long)线程不安全,则可能余额被减成负数。

    public class AccountCAS extends Thread{
        private Account account;
        public AccountCAS(Account account){
            super();
            this.account = account;
        }
        
        @Override
        public void run() {
            
            try {
                Thread.sleep(500);
                account.withDraw(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            final int NUM = 5;
            Account ac = new Account();
            for(int i=0;i<NUM;++i){
                new AccountCAS(ac).start();
            }
        }
    
    }
    
    class Account{
        /**
         * 余额
         */
        private AtomicLong balance = new AtomicLong(10000);
        
        public void withDraw(long money){
            long oldValue = balance.get();
            if(oldValue>=money){
                while(true){
                    if(balance.compareAndSet(oldValue, oldValue-money)){
                        System.out.println(Thread.currentThread().getName()+" withDraw:"+money);
                        break;
                    }
                }
            }
        }
    }

    运行结果如下:

    Thread-0 withDraw:4000

    Thread-3 withDraw:4000

    以上的Lock-free算法不需要加锁,通常包含以下几点:1.原子变量 2.循环 3.CAS 4.退出

  • 相关阅读:
    20151019
    20151013
    20150810
    20150626
    20150625
    20150530
    HTML特殊字符大全
    label标签跳出循环
    IIS 负载均衡
    .NET代码执行效率优化
  • 原文地址:https://www.cnblogs.com/dreamysmurf/p/4009110.html
Copyright © 2020-2023  润新知