Java 实现一个自己的显式锁Lock(有超时功能)

时间:2024-01-08 21:14:38

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...