接口
package com.thread.createmyselflock;
import java.util.Collection;
public interface Lock {
class TimeOutException extends Exception{
public TimeOutException(String messgae){
super(messgae);
}
}
//定义锁,允许中断
void lock() throws InterruptedException;
//定义等待时间,如果没有获取到锁,就中断,抛出异常
void lock(long mills) throws InterruptedException, TimeOutException;
//释放锁
void unlock();
//保存被锁住的线程
Collection<Thread> getBlockedThread();
//获取被锁住的线程的个数
int getBlockedsize();
}
锁
package com.thread.createmyselflock;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class BooleanLock implements Lock {
//initValue = true 锁已经被获取
//initValue = false 锁没有被获取,线程可以获取
private boolean initValue;
//保存被locked的线程的集合
private Collection<Thread> collection = new ArrayList<>();
//定义一个上锁开锁线程,也就是我上的锁,必须有我来开,避免被别的线程打开锁
private Thread currentThread;
//构造函数初始化
public BooleanLock(){
this.initValue = false;
}
@Override
public synchronized void lock() throws InterruptedException {
while (initValue){
collection.add(Thread.currentThread());
this.wait();
}
//记录获得锁的线程
currentThread = Thread.currentThread();
//获得到锁,从等待集合中将该线程删除
collection.remove(Thread.currentThread());
initValue = true;
}
/**
*
* @param mills 为了得到锁线程最多等待的秒数,如果超过mills,线程就中断等待,去做别的事情
* @throws InterruptedException
* @throws TimeOutException
*/
@Override
public synchronized void lock(long mills) throws InterruptedException, TimeOutException {
//如果输入的时间不符合规范,那你得不到锁就一直等待
if (mills<=0){
lock();
}
long hasWaiting = mills;
long endTime = System.currentTimeMillis()+mills;
while (initValue){
if (hasWaiting<=0){
throw new TimeOutException(Thread.currentThread()+"等待超时");
}
collection.add(Thread.currentThread());
this.wait(mills);
hasWaiting = endTime - System.currentTimeMillis();
}
initValue = true;
//获得到锁,从等待集合中将该线程删除
collection.remove(Thread.currentThread());
//记录获得锁的线程
currentThread = Thread.currentThread();
}
@Override
public synchronized void unlock() {
//判读是不是获得锁的线程,只有是获得锁的线程才有资格释放锁
if (Thread.currentThread()==currentThread){
//释放锁
initValue = false;
System.out.println(Thread.currentThread()+"释放锁");
this.notifyAll();
}
}
@Override
public Collection<Thread> getBlockedThread() {
//为了保证线程安全,不允许被别的线程修改集合
return Collections.unmodifiableCollection(collection);
}
@Override
public int getBlockedsize() {
return collection.size();
}
}
测试
package com.thread.createmyselflock;
import java.util.Optional;
import java.util.stream.Stream;
public class LockTest {
public static void main(String[] args) {
//定义锁
final BooleanLock BOOLEANLOCK = new BooleanLock();
Stream.of("t1","t2","t3","t4")
.forEach(name->new Thread(()->{
//首先获取锁
try {
BOOLEANLOCK.lock(10L);
Optional.of(Thread.currentThread().getName()+"获得锁")
.ifPresent(System.out::println);
work();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Lock.TimeOutException e) {
Optional.of(e.getMessage())
.ifPresent(System.out::println);
} finally {
BOOLEANLOCK.unlock();
}
},name).start());
}
private static void work() throws InterruptedException{
Optional.of(Thread.currentThread().getName()+"在工作")
.ifPresent(System.out::println);
Thread.sleep(5_000);
}
}