ReentrantLock 样例code
Topic source程序有问题
如果tryLock 1s内没有获取到资源,之后lock.unlock() 会有无锁可解的错误
所以在解锁前可作判断 lock.islocked() 或者 将 lock.unlock() 嵌入tryLock判断之内,
但不知为何,我的ReentrantLock 中没有 islocked 方法,那只能先手动设置标志位了
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html
原来是 lock 类型错误 ,应该定义为 ReentrantLock 而不是 Lock
但这样还是有错误,当把doSomething的延时时间调整为 1500
单纯通过 lock.isLocked() 判断解锁,会错误的对其他正在占用该锁的线程解锁
使用 lock.isHeldByCurrentThread() 可以确认是否是当前线程占用此lock,
这样配合 lock.isLocked() 就能判断是否需要解锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
// import java.util.concurrent.locks.*;
import java.util.concurrent.TimeUnit;
public class ReentrantLockTest {
public static void main(String[] args) {
// same Resource and Lock
Resource r = new Resource();
final ReentrantLock lock = new ReentrantLock();
for (int i = 1; i < 5; i++) {
// final int c = i;
Thread t = new Thread(new ConcurrencyLockExample(r, lock, i));
t.start();
}
}
}
class Resource {
private int m = 0;
public void doSomething(int n) {
// do some operation, DB read, write etc
m += n;
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
}
}
public void doLogging() {
// logging, no need for thread safety
}
public int getM() {
return m;
}
}
class ConcurrencyLockExample implements Runnable {
private Resource resource;
private ReentrantLock lock;
private String tN;
private boolean taskToDo = true;
public ConcurrencyLockExample(Resource r, ReentrantLock lock, int tN) {
this.resource = r;
this.tN = "Thread_" + tN;
this.lock = lock;
}
@Override
public void run() {
while (taskToDo) {
try {
System.out.println(tN + " try to get Resource");
if (lock.tryLock() || lock.tryLock(1, TimeUnit.SECONDS)) {
System.out.println(tN + " GoT Resource");
resource.doSomething(10);
System.out.println(tN + " Processed Resource: " + resource.getM());
taskToDo = false;
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// release lock
if (lock.isHeldByCurrentThread() && lock.isLocked()) {
System.out.println(tN + " releasing Resource");
lock.unlock();
System.out.println(tN + " released Resource");
}
}
}
resource.doLogging();
}
}
回复“如果tryLock 1s内没有获取到资源,之后lock.unlock() 会有无锁可解的错误”。没有获取到锁就别unlock了呀。你看老师的unlock代码也是写在tryLock成功里面的呀。
- 1
Junes_99994
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.TimeUnit;
public class ReentrantLockTest {
public static void main(String[] args) {
// same Resource and Lock
Resource r = new Resource();
final Lock lock = new ReentrantLock();
for (int i = 1; i < 5; i++) {
// final int c = i;
Thread t = new Thread(new ConcurrencyLockExample(r, lock, i));
t.start();
}
}
}
class Resource {
private int m = 0;
public void doSomething(int n) {
// do some operation, DB read, write etc
m += n;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
public void doLogging() {
// logging, no need for thread safety
}
public int getM() {
return m;
}
}
class ConcurrencyLockExample implements Runnable {
private Resource resource;
private Lock lock;
private String tN;
public ConcurrencyLockExample(Resource r, Lock lock, int tN) {
this.resource = r;
this.tN = "Thread_" + tN;
this.lock = lock;
}
@Override
public void run() {
try {
System.out.println(tN + " try to get Resource");
if (lock.tryLock(1, TimeUnit.SECONDS)) {
System.out.println(tN + " GoT Resource");
resource.doSomething(10);
System.out.println(tN + " Processed Resource: " + resource.getM());
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// release lock
System.out.println(tN + " releasing Resource");
lock.unlock();
System.out.println(tN + " released Resource");
}
resource.doLogging();
}
}