lock接口
package com.dwz.concurrency.chapter10; import java.util.Collection; public interface Lock { class TimeOutException extends Exception { public TimeOutException(String message) { super(message); } } void lock() throws InterruptedException; void lock(long mills) throws TimeOutException, InterruptedException; void unlock(); Collection<Thread> getBlockedThread(); int getBlockedSize(); }
lock实现类
package com.dwz.concurrency.chapter10; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Optional; /** * 实现一个显示锁lock,并保证锁是由自己释放 */ public class BooleanLock implements Lock { //The initValue is true indicated the lock have be get. //The initValue is false indicated the lock is free(other thread can get this.) private boolean initValue; //保证该锁只能被当前线程释放 private Thread currentThread; private Collection<Thread> blockedThreadCollection = new ArrayList<>(); public BooleanLock() { this.initValue = false; } @Override public synchronized void lock() throws InterruptedException { while (initValue) { blockedThreadCollection.add(Thread.currentThread()); Optional.of(Thread.currentThread().getName() + " add the blockedThreadCollection....").ifPresent(System.out::println); this.wait(); } blockedThreadCollection.remove(Thread.currentThread()); this.initValue = true; this.currentThread = Thread.currentThread(); } @Override public synchronized void lock(long mills) throws TimeOutException, InterruptedException { if(mills <= 0) { lock(); } long hasRemaining = mills; long endTime = System.currentTimeMillis() + mills; while(initValue) { if(hasRemaining <= 0) { throw new TimeOutException("Time out"); } blockedThreadCollection.add(Thread.currentThread()); this.wait(mills); hasRemaining = endTime - System.currentTimeMillis(); } blockedThreadCollection.remove(Thread.currentThread()); this.initValue = true; this.currentThread = Thread.currentThread(); } @Override public synchronized void unlock() { if(Thread.currentThread() == currentThread) { this.initValue = false; Optional.of(Thread.currentThread().getName() + " release the lock monitor....").ifPresent(System.out::println); this.notifyAll(); } } @Override public Collection<Thread> getBlockedThread() { return Collections.unmodifiableCollection(blockedThreadCollection); } @Override public int getBlockedSize() { return blockedThreadCollection.size(); } }
测试代码
package com.dwz.concurrency.chapter10; import java.util.Optional; import java.util.stream.Stream; import com.dwz.concurrency.chapter10.Lock.TimeOutException; /** * 多线程的lock */ public class LockTest2 { private static void work() throws InterruptedException { Optional.of(Thread.currentThread().getName() + " is working...").ifPresent(System.out::println); Thread.sleep(2_000); } public static void main(String[] args) throws InterruptedException { final BooleanLock booleanLock = new BooleanLock(); Stream.of("T1", "T2", "T3", "T4") .forEach(name -> new Thread(() -> { try { booleanLock.lock(6000L); Optional.of(Thread.currentThread().getName() + " have the lock Monitor...").ifPresent(System.out::println); work(); } catch (InterruptedException e) { e.printStackTrace(); } catch (TimeOutException e) { Optional.of(Thread.currentThread().getName() + " time out...").ifPresent(System.out::println); } finally { booleanLock.unlock(); } }, name).start() ); } }