java lock锁的是什么意思_浅析JAVA Lock锁原理

同样是锁,先说说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(); //线程阻塞

}

}

}

看完的小伙伴可以去看JDK提供的Lock源码啦。。

以上就是浅析JAVA Lock锁原理的详细内容,更多关于JAVA Lock锁原理的资料请关注脚本之家其它相关文章!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值