-
(1) Lock是一个接口, 它提供了一种无条件的、可轮询的、定时的、可中断的锁获取操作m 所有加锁和解锁的方法都是__显式__的
public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition(); }
(2) Lock的实现中, 和内置锁synchronized的内存可见性语义相同, 在加锁语义、调度算法、顺序保证以及性能特性等方面有所不同
-
(1) ReentrantLock是Lock接口的一种实现, 它与synchronized具有相同的互斥性和内存可见性
(2) 使用Lock时, 必须显式unlock(), 否则永远不会被释放, 所以要在finally中释放
Lock lock = new ReentrantLock(); lock.lock(); try { ... } catch () { ... } finally { lock.unlock(); }
-
使用Lock作为__轮询锁__
(1) 示例
public class DeadlockAvoidance { ... public boolean transferMoney( Account fromAcct, Account toAcct, DollarAmount amount, long timeout, TimeUnit unit) throws InsufficientFundsException, InterruptedException { long fixedDelay = getFixedDelayComponentNanos(timeout, unit); long randMod = getRandomDelayModulusNanos(timeout, unit); long stopTime = System.nanoTime() + unit.toNanos(timeout); while (true) { if (fromAcct.lock.tryLock()) { try { if (toAcct.lock.tryLock()) { try { if (fromAcct.getBalance().compareTo(amount) < 0) { throw new InsufficientFundsException(); } else { fromAcct.debit(amount); toAcct.credit(amount); return true; } } finally { toAcct.lock.unlock(); } } } finally { fromAcct.lock.unlock(); } } if (System.nanoTime() > stopTime) { return false; } NANOSECONDS.sleep(fixedDelay + rnd.nextLong() % randMod); } } ... }
(2) boolean tryLock();方法的含义是
/** * * <p>Acquires the lock if it is available and returns immediately * with the value {@code true}. * * If the lock is not available then this method will return * immediately with the value {@code false}. * * <p>A typical usage idiom for this method would be: * <pre> {@code * Lock lock = ...; * if (lock.tryLock()) { * try { * // manipulate protected state * } finally { * lock.unlock(); * } * } else { * // perform alternative actions * }}</pre> * * This usage ensures that the lock is unlocked if it was acquired, and * doesn't try to unlock if the lock was not acquired.
所以无论是否获得到了锁都会立刻返回, 因此可以用作轮询
-
使用Lock作为__定时锁__
(1) 示例
public class TimedLocking { private Lock lock = new ReentrantLock(); public boolean trySendOnSharedLine(String message, long timeout, TimeUnit unit) throws InterruptedException { long nanosToLock = unit.toNanos(timeout) - estimatedNanosToSend(message); if (!lock.tryLock(nanosToLock, NANOSECONDS)) { return false; } try { return sendOnSharedLine(message); } finally { lock.unlock(); } } ... }
(2) boolean tryLock(long time, TimeUnit unit) throws InterruptedException;方法的语义是
/** * Acquires the lock if it is free within the given waiting time and the * current thread has not been {@linkplain Thread#interrupt interrupted}. * * <p>If the lock is available this method returns immediately * with the value {@code true}. * If the lock is not available then * the current thread becomes disabled for thread scheduling * purposes and lies dormant until one of three things happens: * <ul> * <li>The lock is acquired by the current thread; or * <li>Some other thread {@linkplain Thread#interrupt interrupts} the * current thread, and interruption of lock acquisition is supported; or * <li>The specified waiting time elapses * </ul> * * <p>If the lock is acquired then the value {@code true} is returned. * * <p>If the current thread: * <ul> * <li>has its interrupted status set on entry to this method; or * <li>is {@linkplain Thread#interrupt interrupted} while acquiring * the lock, and interruption of lock acquisition is supported, * </ul> * then {@link InterruptedException} is thrown and the current thread's * interrupted status is cleared. * * <p>If the specified waiting time elapses then the value {@code false} * is returned. * If the time is less than or equal to zero, the method will not wait at * all. * * @param time the maximum time to wait for the lock * @param unit the time unit of the {@code time} argument * @return {@code true} if the lock was acquired and {@code false} * if the waiting time elapsed before the lock was acquired * * @throws InterruptedException if the current thread is interrupted * while acquiring the lock (and interruption of lock * acquisition is supported) */
(3) 所以可以用来作为定时锁, 期间发生了中断也可以抛出去或者处理之
-
使用Lock作为__可中断的锁__
(1) 示例
public class InterruptibleLocking { private Lock lock = new ReentrantLock(); public boolean sendOnSharedLine(String message) throws InterruptedException { lock.lockInterruptibly(); try { return cancellableSendOnSharedLine(message); } finally { lock.unlock(); } } private boolean cancellableSendOnSharedLine(String message) throws InterruptedException { /* send something */ return true; } }
(2) void lockInterruptibly() throws InterruptedException;语义
/** * Acquires the lock unless the current thread is * {@linkplain Thread#interrupt interrupted}. * * <p>Acquires the lock if it is available and returns immediately. * * <p>If the lock is not available then the current thread becomes * disabled for thread scheduling purposes and lies dormant until * one of two things happens: * * <ul> * <li>The lock is acquired by the current thread; or * <li>Some other thread {@linkplain Thread#interrupt interrupts} the * current thread, and interruption of lock acquisition is supported. * </ul> * * <p>If the current thread: * <ul> * <li>has its interrupted status set on entry to this method; or * <li>is {@linkplain Thread#interrupt interrupted} while acquiring the * lock, and interruption of lock acquisition is supported, * </ul> * then {@link InterruptedException} is thrown and the current thread's * interrupted status is cleared. * * @throws InterruptedException if the current thread is * interrupted while acquiring the lock (and interruption * of lock acquisition is supported) */
(3) 如果既要定时又要可中断, 使用带定时的tryLock方法
chapter13_显式锁_1_Lock与ReentrantLock
猜你喜欢
转载自blog.csdn.net/captxb/article/details/88648597
今日推荐
周排行