当前位置: 首页 > 科技观察

Java多线程专题Lock的使用_0

时间:2023-03-16 17:34:43 科技观察

Lock基本都是用Lock,它是java.util.concurrent.locks下的一个接口,也是用来处理线程同步问题的。公共接口锁{voidlock();voidlockInterruptibly()抛出InterruptedException;布尔tryLock();booleantryLock(longtime,TimeUnitunit)throwsInterruptedException;无效解锁();如果锁不可用,则出于线程调度目的禁用当前线程并休眠直到获取锁。lockInterruptibly()获取锁,除非当前线程被中断。如果可用,获取锁并立即返回。如果锁不可用,则出于线程调度目的禁用当前线程并休眠,直到当前线程获取锁或另一个线程中断当前线程。tryLock()的这种使用保证了锁在获取到的时候就解锁,没有获取到的时候不会去尝试解锁。返回布尔类型(true/false)。tryLock(longtime,TimeUnitunit)如果在给定的等待时间内空闲并且当前线程没有被中断,则获取锁。如果锁可用,此方法立即返回值true。如果锁不可用,则出于线程调度目的禁用当前线程并休眠,直到当前线程获取锁、被中断或指定的等待时间结束。unlock()释放锁。newCondition()返回绑定到此Lock实例的新Condition实例。因为它只是一个接口,所以我们需要找到它的实现类。下面将着重介绍ReentrantLock,它也是我们工作中常用的。ReentrantLock它是一个可重入互斥锁,具有与使用同步方法和语句访问的隐式监视器锁相同的基本行为和语义,但具有扩展功能。说了这么多,还没带大家去体验呢。让我们用一个例子来尝试一下。publicclassLockTest{privatestaticLocklock=newReentrantLock();私有静态整数计数=0;privatestaticvoidadd(){try{//锁定lock.lock();计数++;//可重入锁reduce();}finally{//记得释放锁lock.unlock();System.out.println(计数);}}privatestaticvoidreduce(){//锁定lock.lock();数数-;//释放锁lock.unlock();}publicstaticvoidmain(String[]args)throwsInterruptedException{for(inti=0;i<100;i++){newThread(LockTest::add).start();}}}我们发现无论执行多少次,结果都和预期的一样,都是0,我们再看看tryLock,直接重写reduce:privatestaticvoidreduce1(){if(lock.tryLock()){尝试{计数--;}finally{//释放锁lock.unlock();}}else{System.out.println("no");}}通过上面的用法,我们来和Synchronized做个对比。从表面上看,一个是关键字,一个是类。在使用上,Synchronized是隐式的,需要显示Lock,对代码要求比较高。如果忘记释放锁,可能会造成死锁。Lock提供了tryLock方法,使程序更加灵活。在代码性能上,Lock更加灵活,可以在不同的方法中执行。结语本节主要讲一下它的基本使用。大家可以举一反三,试试看哪些情况会导致死锁。