天天看点

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

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