Java 實現一個自己的顯式鎖Lock(有超時功能)
阿新 • • 發佈:2019-02-15
while import val final current mean edt nor sync
Lock接口
package concurency.chapter9; import java.util.Collection; public interface Lock { static class TimeOutException extends Exception { TimeOutException(String message) { super(message); } } void lock() throws InterruptedException; void lock(long mills) throws InterruptedException,TimeOutException; void unlock(); Collection<Thread> getBlockedThread(); int getBlockedSize(); }
Lock實現類
package concurency.chapter9; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Optional; public class BooleanLock implements Lock{ public BooleanLock(boolean initValue) { this.initValue = initValue; } // false means is free // true means having been used private boolean initValue; private Thread currentThread; private Collection<Thread> blockedThreads = new ArrayList<>(); @Override public synchronized void lock() throws InterruptedException { while(initValue) { blockedThreads.add(Thread.currentThread()); this.wait(); } blockedThreads.remove(Thread.currentThread()); this.initValue = true; this.currentThread = Thread.currentThread(); } @Override public synchronized void lock(long mills) throws InterruptedException, TimeOutException { // less than 0, Ignore it.. if(mills <= 0) lock(); long hasRemaining = mills; long endTime = System.currentTimeMillis() + mills; while(initValue) { if(hasRemaining <= 0) throw new TimeOutException("time out, and the Thread[" + Thread.currentThread().getName()+"] do not get the lock"); blockedThreads.add(Thread.currentThread()); this.wait(mills); hasRemaining = endTime - System.currentTimeMillis(); } blockedThreads.remove(Thread.currentThread()); this.initValue = true; this.currentThread = Thread.currentThread(); } @Override public synchronized void unlock() { if(currentThread != null && Thread.currentThread() == currentThread) { this.initValue = false; Optional.of(Thread.currentThread().getName() + " release the lock...").ifPresent(System.out::println); this.notifyAll(); } } @Override public Collection<Thread> getBlockedThread() { return Collections.unmodifiableCollection(blockedThreads); } @Override public int getBlockedSize() { return blockedThreads.size(); } }
測試
package concurency.chapter9; import java.util.Optional; import java.util.stream.Stream; public class LockTest { public static void main(String[] args) throws InterruptedException { final BooleanLock booleanLock = new BooleanLock(false); Stream.of("T1", "T2", "T3", "T4") .forEach(name -> new Thread(() -> { try { booleanLock.lock(1000L); Optional.of(Thread.currentThread().getName() + " have the lock Monitor") .ifPresent(System.out::println); work(); } catch (InterruptedException e) { e.printStackTrace(); } catch (Lock.TimeOutException e) { System.out.println(e.getMessage()); // Optional.of(Thread.currentThread().getName() + " time out") // .ifPresent(System.out::println); } finally { booleanLock.unlock(); } }, name).start() ); } private static void work() throws InterruptedException { Optional.of(Thread.currentThread().getName() + " is Working...") .ifPresent(System.out::println); Thread.sleep(10_000); } }
測試結果
T1 have the lock Monitor
T1 is Working...
time out, and the Thread[T2] do not get the lock
time out, and the Thread[T3] do not get the lock
time out, and the Thread[T4] do not get the lock
T1 release the lock...
Java 實現一個自己的顯式鎖Lock(有超時功能)