Custom Display Lock

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);
    }
}

Keywords: Java Programming

Added by zizzy80 on Sat, 05 Oct 2019 10:01:37 +0300