JAVA语言多线程锁的知识实例讲解
小标 2018-10-12 来源 : 阅读 988 评论 0

摘要:本文主要向JAVA语言多线程锁的知识实例讲解大家介绍了,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

本文主要向JAVA语言多线程锁的知识实例讲解大家介绍了,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。


Lock


Lock提供了与synchronized类似的同步功能,只是在显式的获取和释放锁,因此有了锁获取和释放的可操作性、可中断的获取锁以及超时获取锁等多种同步特性。


代码实例:


Lock lock = new ReentrantLock();

lock.lock();

try{

}finally{

 lock.unlock();

}

   


特性


尝试非阻塞地获取锁:当前线程尝试获取锁,如果这一时刻锁没有被其它线程获取到,则成功获取并持有锁; 能被中断地获取锁:获取到的锁的线程能够响应中断,当获取到锁的线程被中断时,中断异常将会抛出,同时锁被释放; 超时获取锁:在指定时间后获取锁,如果时间到了无法获取,则返回


队列同步器


队列同步器是用来构建锁或其它同步组件的基础框架


它使用一个int变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作


重写同步器指定方法是,需要使用以下3个方法访问或修改同步状态


getState():获取当前同步状态 setState(int newState):设置当前同步状态 compareAndSetState(int expect, int update):使用CAS设置当前状态,保证状态设置原子性


重入锁


ReentrantLock:支持重进入的锁,可以支持一个线程对资源的重复加锁,同时还支持获取锁时的公平和非公平性选择。


重进入指任意线程在获取锁之后能够再次获取该锁而不会被锁所阻塞,主要解决以下两个问题:


线程再次获取锁:如果获取锁的线程为当前占据锁的线程,则再次获取成功; 锁的最终释放:在第n次释放该锁后,其他线程能够获取该锁;


公平是通过判断同步队列中是否有前驱节点来判断线程请求锁的早晚,从而让最早请求锁的线程获取锁。


公平性锁保证了FIFO原则,但是代价是造成了大量的线程切换。非公平性锁可能造成一个线程频繁可以获取锁,使其它线程“饥饿”,但是这样会减少线程切换,保证了吞吐量。


读写锁


读写锁维护了一对锁,一个读锁,一个写锁。当写锁被获取到时,后续的读写操作都会被阻塞,写锁释放后,所有操作继续执行。


特性


公平性选择:支持非公平和公平的锁获取方式; 重进入:支持重进入,读线程可以再次获取锁,写线程可以再次获取写锁,同时可以获取读锁; 锁降级:遵循获取写锁、获取读锁、释放写锁的次序


代码实例


static Map<string,object>map = new HashMap<string,object>();

static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

static Lock r = rwl.readLock();

static Lock w = rwl.writeLock();

 

public static final Object get(String key){

 r.lock();

 try{

  return map.get(key);

 }finally{

  r.unlock();

 }

}

 

public static final Object put(String key, Object value){

 w.lock();

 try{

  return map.put(key,value);

 }finally{

  w.unlock

 }

}

 

public static final void clear(){

 w.lock();

 try{

  map.clear();

 }finally{

  w.unlock();

 }

}</string,object></string,object>

   


Condition接口


Condition接口提供了类似Object的监视器方法


Condition对象由Lock对象创建


Condition定义了等待/通知两种类型的方法,当前线程调用这些方法时,需要提前获取到Condition对象关联的锁


代码实例


Lock lock = new ReentrantLock();

Condition condition = lock.newCondition();

 

//当前线程进入等待状态直到被通知或中断

public void conditionWait() throws InterruptedException{

 lock.lock();

 try{

  condition.await();

 }finally{

  lock.unlock();

 }

}

 

//唤醒一个等待在Condition上的线程

public void conditionSignal() throws InterruptedException{

 lock.lock();

 try{

  condition.signal();

 }finally{

  lock.unlock();

 }

}

   


有界队列实例


public class BoundedQueue<t>{

 private Object[] items;

 //添加下标、删除下标、数组当前数量

 private int addIndex, removeIndex, count;

 private Lock lock = new ReentrantLock();

 private Condition notEmpty = lock.newCondition();

 private Condition notFull = lock.newCondition();

 

 public BoundedQueue(int size){

  items = new Object[size];

 }

 

 //添加元素,如果数组满,则该线程进入等待状态,直到有空位

 public void add(T t) throws InterruptedException{

  lock.lock();

  try{

while(count == items.length){

 notFull.await();

}

items[addIndex] = t;

if(++addIndex == items.length){ 

 addIndex = 0; 

}

++count;

notEmpty.signal();

  }finally{

lock.unlock();

  }

 }

 

 //删除元素,如果数组空,则该线程进入等待状态,直到有新添加元素

 @SuppressWarnings("unchecked")

 public T remove() throws InterruptedException{

  lock.lock();

  try{

while(count == 0){

 notEmpty.await();

}

Object x = items[removeIndex];

if(++removeIndex == items.length){

 removeIndex = 0;

}

--count;

notFull.signal();

return (T)x;

  }finally{

lock.unlock();

  }

 }

}</t>

   


小结


Lock和synchronized比较而言,Lock能完成synchronized所实现的所有功能;


但是Lock有比synchronized更精确的线程语义和更好的性能;


synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。


          

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!


本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程