ReentrantLock与synchronized相比,synchronized在代码块执行完后会自动解锁,异常也会自动解锁,单reentrantLock需要手动加锁何解锁。
public class Study05 {
public static void main(String[] args) {
Study05 study =new Study05();
new Thread(study :: m1).start();
try {
TimeUnit.SECONDS.sleep(1);
}catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(study :: m2).start();
}
Locklock =new ReentrantLock();
void m1(){
try {
lock.lock();
for (int i =0; i <10; i++) {
TimeUnit.SECONDS.sleep(1);
System.out.println(i);
}
}catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
void m2(){
try {
lock.lock();
System.out.println("m2...");
} finally {
lock.unlock();
}
}
}
运行结果:
0
1
2
3
4
5
6
7
8
9
m2...
在m1中reentrantLock没释放之前不会执行m2中的语句。
ReentrantLock还有些功能比synchronized强大。
1.tryLock尝试加锁,synchronized如果没有获取到锁就会一直阻塞,但tryLock可以指定等待时间,到达指定时间后,不管是否获得锁,方法都将得到执行。
public class Study05 {
public static void main(String[] args) {
Study05 study =new Study05();
new Thread(study::m3).start();
new Thread(study::m4).start();
}
Locklock =new ReentrantLock();
void m3(){
try{
lock.lock();
for (int i=0; i<10; i ++){
TimeUnit.SECONDS.sleep(1);
System.out.println(i);
}
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
void m4(){
try {
boolean locked =lock.tryLock(5, TimeUnit.SECONDS);
System.out.println("m4..."+ locked);
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
运行结果:
0
1
2
3
m4...false
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151) at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java1261) at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457) at study.Study05.m4(Study05.java:67) at java.lang.Thread.run(Thread.java:748)
4
5
6
7
8
9
因为m4没获得锁却在finally中释放锁,所以会报错
2.lock.lockInterruptibly()
3.ReentrantLock可以指定为公平锁
Lock lock = new ReentrantLock(true);//参数为true表示公平锁
网友评论