java中为了解决多线程并发带来的线程安全问题,引入了锁机制。

     一、公平锁和非公平锁

  1、公平锁:按照申请锁的顺序(FIFO队列)来获取锁。

      2、非公平锁:所有线程都会竞争,获取的锁的顺序和申请顺序无关。

ReentrantLock failReentrantLock = new ReentrantLock(true); //公平锁

ReentrantLock unFairReentrantLock = new ReentrantLock(); // 非公平锁

 

     二、共享锁和独占锁

      1、共享锁:又称读锁,支持多个线程同时获取锁,可以读数据,无法更新。

      2、独占锁:又称写锁,一次只能由一个线程访问。可以更新数据。

ReadWriteLock readWriteLock = new ReadWriteLock() {
       @Override
            public Lock readLock() {
                return null;
            }

            @Override
            public Lock writeLock() {
                return null;
            }
 };

  三、乐观锁和悲观锁

      1、乐观锁:每次获取数据不认为会有其他线程修改数据,乐观的认为不会产生并发问题。因此在读数据时候不会加锁,但在更新时候会check其他线程有没有对数据进行过修改。

      check方式一般有两种:(1)版本号机制 (2)cas操作

      对于版本号机制,会为数据加上一个版本号字段(version),每更新一次数据,version+1。如果线程要更新数据值,会读取数据和对应version。提交更新时,

      如果version和数据在数据库中version 一致则更新,否则重试。 sql:    

  update table set x=x+1, version=version+1 where id=#{id} and version=#{version};

      对于cas操作:即compare and set,涉及三个操作数,数据所在的内存值,预期值,新值。如果更新数据,会check内存值和之前取到的值是否相等,如果相等用新值更新,否则

      自旋,即不断重试。

      2、悲观锁:每次获取数据认为会有其他线程修改数据,悲观的认为一定会产生并发问题。因此每次获取数据之前都会加锁。比如java中 synchronized。

 

posted on 2017-05-03 11:50  知己一生  阅读(275)  评论(0编辑  收藏  举报