老师实现的SpinLock不能中断,虽然在您另外一个课中提到不要用volatile flag的方式进行中断,但这里是不是可以用volatile flag个方式来实现中断的响应呢?不知道我这样写有没有缺陷,另外想问下老师JDK有没有提供现成的基于CAS实现的锁类似SpinLock?
public class SpinLock {
private AtomicReference sign = new AtomicReference<>();
private volatile boolean interrupted;
public void lock() {
Thread cur = Thread.currentThread();
while (!sign.compareAndSet(null, cur)) {
//没有获得锁,自旋等待
}
}
public void unlock() {
Thread cur = Thread.currentThread();
sign.compareAndSet(cur, null);
}
public boolean tryLock() throws InterruptedException {
Thread cur = Thread.currentThread();
while (!sign.compareAndSet(null, cur)) {
//没有获得锁,自旋等待
if (interrupted) {
throw new InterruptedException();
}
}
return true;
}
public void interrupt() {
this.interrupted = true;
}
public boolean tryLock(long time) throws InterruptedException {
long startTime = System.currentTimeMillis();
Thread cur = Thread.currentThread();
while (!sign.compareAndSet(null, cur)) {
//没有获得锁,自旋等待
if (interrupted) {
//处理中断
throw new InterruptedException();
}
long diff = System.currentTimeMillis() - startTime;
if (diff >= time) {
//处理超时
System.out.println("超时:" + diff + "ms");
return false;
}
}
return true;
}
public static void main(String[] args) throws InterruptedException {
SpinLock spinLock = new SpinLock();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
spinLock.lock();
System.out.println(Thread.currentThread().getName() + "获得锁成功");
Thread.sleep(1000 * 1);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
spinLock.unlock();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
//是否获取锁的标志位
boolean flag = false;
try {
flag = spinLock.tryLock(3000);
if (flag) {
System.out.println(Thread.currentThread().getName() + "获得锁成功");
} else {
System.out.println(Thread.currentThread().getName() + "获取锁失败");
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + "获得锁");
e.printStackTrace();
} finally {
if (flag) {
spinLock.unlock();
}
}
}
});
t1.start();
Thread.sleep(100);
t2.start();
}
}