集团主站
欢迎来到成都达内官方网站!达内—美国上市公司 亿元级外企IT培训企业!
成都it培训哪家好
成都it培训哪家好
全国服务监督电话:15023458194  |   联系客服   |
当前位置:主页 > 培训课程 > Java >

成都java培训:带你理解Lock锁原理

发布者: 成都达内     浏览次数:     发布时间:2020-07-24 10:48:46

同样是锁,先说说synchronized和lock的区别:synchronized可以锁住代码块,对象和类,但是线程从开始获取锁之后开发者不能进行控制和了解;lock则用起来非常灵活,提供了许多api可以让开发...

  同样是锁,先说说synchronized和lock的区别:

  synchronized是java关键字,是用c++实现的;而lock是用java类,用java可以实现

  synchronized可以锁住代码块,对象和类,但是线程从开始获取锁之后开发者不能进行控制和了解;lock则用起来非常灵活,提供了许多api可以让开发者去控制加锁和释放锁等等。

  写个Demo

  static Lock lock = new ReentrantLock();public static void main(String[] args) throws InterruptedException {

  lock.lock();//其他没拿到锁的卡住不动

  Thread thread = new Thread(new Runnable() {

  @Override

  public void run() {

  System.out.println("start to get lock Interruptibly");

  lock.unlock(); //看看会发生什么,注释掉再看看

  lock.lock();

  System.out.println("拿到锁");

  lock.unlock();

  System.out.println("释放锁");

  }

  });

  thread.start();

  Thread.sleep(3000);

  lock.unlock();

  }

  我们自己来手写一下lock接口的tryLock()、lock()和unLock()方法,实现我们自己的myLock。

  public class MyLock implements Lock {

  //多并发调用 0-未占用 大于0-占用

  AtomicInteger state = new AtomicInteger();

  Thread ownerThread = new Thread();

  //等待锁的队列

  LinkedBlockingQueue waiters = new LinkedBlockingQueue();

  @Override

  public void lock() {

  if (!tryLock()) { //先抢锁,所以是非公平锁

  //没拿到锁,放到队列中去进行排队

  waiters.add(Thread.currentThread());

  //等待被唤醒

  for (; ; ) {

  if (tryLock()) { //非公平锁情况下,唤醒过来继续获取锁

  waiters.poll(); //获取锁成功把自己从队列中取出来

  return;

  } else //获取锁失败

  LockSupport.park(); //线程阻塞

  }

  }

  }

  @Override

  public boolean tryLock() {

  if (state.get() == 0) { //如果锁没被占用

  if (state.compareAndSet(0, 1)) { //如果成功拿到锁

  ownerThread = Thread.currentThread(); //占用锁线程改为当前线程

  return true;

  }

  }

  return false;

  }

  @Override

  public void unlock() {

  if (ownerThread != Thread.currentThread()) //占用锁线程不是当前线程无法释放锁

  throw new RuntimeException("非法调用,当前锁不属于你");

  if (state.decrementAndGet() == 0) //如果成功释放锁

  ownerThread = null; //占用锁线程置空

  //通知其他线程

  // Thread thread = null;

  //

  // while ((thread = waiters.peek()) != null)

  // LockSupport.unpark(thread);

  Thread thread = waiters.peek(); //获取队列头部线程,线程还留在队列中

  if (thread != null) {

  LockSupport.unpark(thread); //取消阻塞

  }

  }

  @Override

  public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {

  return false;

  }

  @Override

  public Condition newCondition() {

  return null;

  }

  @Override

  public void lockInterruptibly() throws InterruptedException {

  }

  }

  几个注意点:

  锁的占用状态state是AtomicInteger类型,底层原理是CAS,这是为了保证在多并发情况下线程安全问题;

  当线程1释放锁成功时,获取队列头部线程但并不取出,因为非公平锁模式下,队列头部线程不一定能获取到锁;

  LockSupport的park()和unPark()方法是native方法,可以阻塞,唤醒线程;

  Lock默认是非公平锁,上面实现的也是非公平锁,小伙伴们可以试一试。

  公平锁和非公平锁区别:

  先等待先获取锁是公平锁;先等待也不一定先获取锁,可能被突然到来的线程获取到是非公平锁;

  公平锁的实现:

  @Override

  public void lock() {

  checkQueue();//线程来的时候先不获取锁,而是先检查队列中有没有等待的线程,如果有,直接放入队列,如果没有,再去获取锁

  if (!tryLock()) { //先抢锁,所以是非公平锁

  //没拿到锁,放到队列中去进行排队

  waiters.add(Thread.currentThread());

  //等待被唤醒

  for (; ; ) {

  if (tryLock()) { //非公平锁情况下,唤醒过来继续获取锁

  waiters.poll(); //获取锁成功把自己从队列中取出来

  return;

  } else //获取锁失败

  LockSupport.park(); //线程阻塞

  }

  }

  }

(责任编辑:范老师)
最新开班
  • 成都Java培训班
    免费试听名额发放中...
  • 成都C++培训班
    免费试听名额发放中...
  • 成都PHP培训班
    免费试听名额发放中...
  • 成都网络工程培训班
    免费试听名额发放中...
  • 成都Unity3D培训班
    免费试听名额发放中...
  • 成都大数据培训班
    免费试听名额发放中...
  • 成都uid培训班
    免费试听名额发放中...
  • 成都会计培训班
    免费试听名额发放中...
  • 成都Python培训班
    免费试听名额发放中...
  • 成都嵌入式培训班
    免费试听名额发放中...
  • 成都web培训班
    免费试听名额发放中...
  • 成都软件测试培训班
    免费试听名额发放中...
在线留言
提交

校区地址:成都市锦江区东大街紫东楼端35号明宇金融广场19楼1906室

联系电话:15023458194

公交路线:芷泉街(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:成都市高新区奥克斯广场蜀锦路209号一楼商铺

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

校区地址:成都锦江区东大街芷泉街229号东方广场C座3楼303

联系电话:15023458194

公交路线:芷泉街(188路;115路;515路;236路;505路;501路;84路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:成都市武侯区佳灵路3号红牌楼广场2号写字楼11楼1115号

联系电话:15023458194

公交路线:红牌楼东(11路;92路;100路;111路;139路;g28路;快速公交K1/K2) 地铁路线:红牌楼站(地铁3号线)

校区地址:成都市锦江区红星路二段70号四川日报大厦502-2

联系电话:15023458194

公交路线:市二医院站(6路;49路;102路;5路;37路;g92路;) 地铁路线:地铁市二医院(地铁3号线)

校区地址:成都市锦江区东大街芷泉段229号东方广场C座16层

联系电话:15023458194

公交路线:芷泉街(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:四川省成都市武侯区高新科技孵化园9号园区E座7楼

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

校区地址:成都市高新区奥克斯广场B座1708

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

了解达内动态
关注成都达内教育公众号

首页 | 关于达内 | 课程中心 | 专家师资 | 视频教程 | 学员空间 | 校企合作 | 新闻资讯 | 就业指导 | 网站地图

2016-2025 达内时代科技集团有限公司 版权所有 京ICP证8000853号-56