Background: ** In multithreaded programming, in order to avoid inconsistency of shared data, the operation of shared data must be locked. In java, synchronized keyword can be used to achieve exclusive lock, but there are two major drawbacks in using this keyword:
1. The blocking time of threads cannot be controlled.
2. Blockage is uninterruptible.
In order to avoid the above situation, we can customize the display lock to achieve a customized blocking time and interruptible. The code example is as follows:
1. Define interfaces
package thread; import java.util.List; import java.util.concurrent.TimeoutException; public interface Lock { void lock() throws InterruptedException; void lock(Long time) throws InterruptedException,TimeoutException;//Millisecond void unlock(); List<Thread> getBlockedThreads();//Getting blocked threads }
2. The Realization of Locks
package thread; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeoutException; public class BooleanLock implements Lock { private Thread currentThread; private boolean locked; private final List<Thread> blockedThreads = new ArrayList<>(); @Override public void lock() throws InterruptedException { synchronized (this){ System.out.println("thread"+ Thread.currentThread().getName()+"Get into lock Synchronized code block..."); while (locked){ blockedThreads.add(Thread.currentThread()); System.out.println("thread"+Thread.currentThread().getName()+"Waiting for acquisition of lock object: "+this); this.wait();//Abandoning ownership of locks //In a synchronous block of code, all threads must acquire the lock of this.monitor if they want to continue executing. } blockedThreads.remove(Thread.currentThread()); this.locked = true;//Get lock this.currentThread = Thread.currentThread();//Threads for acquiring locks System.out.println("thread"+this.currentThread.getName()+"Get lock..."); } } /** * Obtain the blocking time of the lock * @param time Unit millisecond * @throws InterruptedException * @throws TimeoutException */ @Override public void lock(Long time) throws InterruptedException, TimeoutException { synchronized (this){ if (time <= 0L){ this.lock(); }else { long remainTime = time; long endTime = System.currentTimeMillis() + remainTime; while (this.locked){ if (remainTime <= 0L){ throw new TimeoutException("can not get lock during "+ time +"ms"); } if (!blockedThreads.contains(Thread.currentThread())){ blockedThreads.add(Thread.currentThread()); } this.wait(remainTime);//waiting time remainTime = endTime -System.currentTimeMillis(); } blockedThreads.remove(Thread.currentThread()); this.locked = true; this.currentThread = Thread.currentThread(); } } } @Override public void unlock() { synchronized (this){ if (Thread.currentThread() == this.currentThread){ this.locked = false; System.out.println("thread" + this.currentThread.getName()+ "Release lock: " + this); this.notifyAll();//Wake up all threads, scramble for this.monitor lock, scramble for runnable status, scramble to continue Blocked } } } @Override public List<Thread> getBlockedThreads() { return Collections.unmodifiableList(this.blockedThreads); } }