lock Interface
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 implementation class
Package com.dwz.concurrency.chapter10; Import of java.util.ArrayList; Import java.util.Collection; Import java.util.Collections; Import java.util.Optional; / ** * achieve a display lock lock, and to ensure that the lock was released by himself * / public class BooleanLock the implements Lock { // at the initValue iS to true Indicated at the Lock have have bE GET. // at the initValue iS false Indicated at the Lock iS as Free (OTHER CAN GET the Thread the this.) Private boolean initValue; // the lock can only guarantee the current thread is released Private the 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(); } }
Test code
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() ); } }