小编这次要给大家分享的是什么是JAVA Lock锁,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。
同样是锁,先说说synchronized和lock的区别:
写个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<Thread> 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 { } }
几个注意点:
Lock默认是非公平锁,上面实现的也是非公平锁,小伙伴们可以试一试。
公平锁和非公平锁区别:
先等待先获取锁是公平锁;先等待也不一定先获取锁,可能被突然到来的线程获取到是非公平锁;
公平锁的实现:
@Override public void lock() { checkQueue();//线程来的时候先不获取锁,而是先检查队列中有没有等待的线程,如果有,直接放入队列,如果没有,再去获取锁 if (!tryLock()) { //先抢锁,所以是非公平锁 //没拿到锁,放到队列中去进行排队 waiters.add(Thread.currentThread()); //等待被唤醒 for (; ; ) { if (tryLock()) { //非公平锁情况下,唤醒过来继续获取锁 waiters.poll(); //获取锁成功把自己从队列中取出来 return; } else //获取锁失败 LockSupport.park(); //线程阻塞 } } }
看完这篇关于什么是JAVA Lock锁的文章,如果觉得文章内容写得不错的话,可以把它分享出去给更多人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。