而这种阻塞有两个比较明显的缺点:
利用java多线程的知识,可以自己动手构造一个BooleanLock,使其在具有synchronized功能的基础之上又具备可中断和超时的功能。
package Lock.BooleanLock;
import java.util.List;
import java.util.concurrent.TimeoutException;
public interface Lock {
//上锁
void lock() throws InterruptedException;
//带超时功能的锁
void lock(long mills) throws InterruptedException, TimeoutException;
//解锁
void unLock();
//获取当前哪些进程被阻塞
List<Thread> getBlockedThreads();
}
package Lock.BooleanLock;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeoutException;
import static java.lang.System.currentTimeMillis;
import static java.lang.Thread.currentThread;
public class BooleanLock implements Lock {
//当前线程
private Thread currentThread;
//是否上锁
private boolean locked = false;
//哪些进程进入了阻塞
private final List<Thread> blockedList = new ArrayList<>();
@Override
public void lock() throws InterruptedException {
synchronized (this){
//获取当前线程
final Thread tempThread = currentThread();
//线程是否进入了阻塞状态,如果进入了加入阻塞队列
while (locked){
try {
if (!blockedList.contains(tempThread)){
blockedList.add(tempThread);
}
this.wait();
}catch (InterruptedException e){
//被中断后移除阻塞队列
blockedList.remove(currentThread());
throw e;
}
}
//如果当前线程没有获取锁,则拿到锁,移除阻塞队列
blockedList.remove(currentThread());
this.locked = true;
this.currentThread = currentThread();
}
}
@Override
public void lock(long mills) throws InterruptedException, TimeoutException {
synchronized (this){
//判断设置超时时间是否<=0
if (mills<=0){
this.lock();
}else {
long remainingMills = mills;
long endMills = currentTimeMillis() +remainingMills;
//该方法同上面一样,加入了计时功能
while (locked){
if (remainingMills<=0){
throw new TimeoutException("不能获得锁");
}
if (!blockedList.contains(currentThread())){
blockedList.add(currentThread());
this.wait(remainingMills);
remainingMills = endMills - currentTimeMillis();
}
}
blockedList.remove(currentThread());
this.locked = true;
this.currentThread = currentThread();
}
}
}
@Override
public void unLock() {
synchronized (this){
if (currentThread == currentThread()){
this.locked = false;
Optional.of(currentThread().getName()+"释放了锁")
.ifPresent(System.out::println);
this.notifyAll();
}
}
}
@Override
public List<Thread> getBlockedThreads() {
//返回不可变的list
return Collections.unmodifiableList(blockedList);
}
}
package Lock.BooleanLock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class BooleanLockTest {
private final Lock lock = new BooleanLock();
public void syncMethod() {
try {
lock.lock(1000);
System.out.println(Thread.currentThread()+"得到了锁");
TimeUnit.SECONDS.sleep(1);
}catch (InterruptedException | TimeoutException e){
e.printStackTrace();
} finally {
lock.unLock();
}
}
public static void main(String[] args) throws InterruptedException {
BooleanLockTest booleanLockTest = new BooleanLockTest();
// IntStream.range(0,10).mapToObj(i-> new Thread(booleanLockTest::syncMethod,"T1"))
// .forEach(Thread::start);
new Thread(booleanLockTest::syncMethod,"t1").start();
Thread t2 = new Thread(booleanLockTest::syncMethod,"T2");
t2.start();
TimeUnit.MILLISECONDS.sleep(10);
}
}
测试超时任务,超时时间小于线程sleep时间,会抛出异常,具体测试可以自己进行。
如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!
加入交流群
请使用微信扫一扫!