首页 > java线程 > java线程中数据同步-lock

java线程中数据同步-lock

作者:bin

除了使用synchronized修饰代码块或者方法,还可以使用Lock方式添加锁,不过要自己释放锁。

区别:
synchronized:是java语言的关键字,是原生语法层面的互斥,需要jvm实现
ReentrantLock:它是JDK 1.5之后提供的API层面的互斥锁,需要lock()和unlock()方法配合try/finally语句块来完成,并且又trylock设置超时放弃锁(trylock()方法未获取到锁后会返回false)

          /**
             * ReentrantLock功能和synchronized一致
             */
            Lock lock = new ReentrantLock();

            /**
             * ReentrantReadWriteLock是读写分离锁
             */
            //Lock lock = new ReentrantReadWriteLock().readLock();
            try {
                //代码块串行,锁上
                lock.lock();
                System.out.println("nihao");
            }finally {
                //解锁
                lock.unlock();
            }

相关锁:java线程中数据同步-synchronized


ReentrantLock(独占锁)的实现原理:
reentranlock:
1.使用state状态来保存锁的占用情况,>1表示锁被占用了。

2.可重入的实现实际上每加一次锁,是对state进行+1,解锁对state-1

3.如果锁未被占用,那么会使用cas进行比较然后设置+1,保证线程安全

4.公平锁:如果锁被占用了,那么新来的线程将加入一个双线链表的表尾,从表头读出一个线程任务,尝试获得锁。

5.非公平锁:如果锁被占用,先尝试获取锁状态,获取不到即进入链表尾部,从表头读出一个线程任务,尝试获得锁。

ReentrantLock的Condition:
类似synchronized的中使用wait呢notify,差异是synchronized中只能对当前锁定对象进行wait即1对1,而lock可以1对多condition。
首先定义一个condition

Lock lock = new ReentrantLock();
Condition con = lock.newCondition();

使用wait

con.await();

使用notify

con.signal();
//con.signalAll();

Semaphore (共享锁)的实现原理
ReetranLock是独占锁,Semaphore是共享锁,
实现的原理和独占锁类似,都是使用Sync类来做的:
1.Semaphore可以设置锁的数量,即同时多少个线程可以并行执行。

2.内部也是通过state去做的,初始化是设置一个state数量,增加线程时对state-1

3.state = 0,表示达到最大线程数量,即锁都被用完了。

4.1.公平锁,新加入的线程先判断是否有等待队列,有就加入队列,没再获取锁。

4.2.非公平锁(默认),新加入的线程先获取锁,获取不到再加入等待队列。原理和reetranlock一样

您必须 [ 登录 ] 才能发表留言!