前言:synchronized和ReentrantLock的区别:
1. 要注意synchronized同步,假如发生异常,JVM是可以帮我们自动释放锁的;但是lock不可以,我们只能手动释放锁,即使发生异常,jvm也不会自动释放锁。
2. synchronized与wait()和notify()/notifyAll()方法结合可以实现等待通知模式;Reentrantlock可以实现同样的功能,在synchronized当中,被通知的线程是由JVM随机选择,但是lock结合condition可以实现选择性通知。
ReentrantLock + lock + condition 使用举例:
备注:注意在condition.await()方法调用之前,必须先lock.lock()获得锁。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyService {
private Lock lock=new ReentrantLock();
public Condition conditionA=lock.newCondition(); //1. Condition 通过Lock(ReentrantLock)生成
public Condition conditionB=lock.newCondition();
public void awaitA(){
try {
lock.lock();
System.out.println("begin awaitA时间为"+System.currentTimeMillis()
+"ThreadName="+Thread.currentThread().getName());
conditionA.await();
System.out.println("end awaitA 时间为"+System.currentTimeMillis()
+"ThreadName"+Thread.currentThread().getName());
}catch (InterruptedException e){
e.printStackTrace();
}finally {
lock.unlock(); //2. 推荐方式:ReentrantLock 锁必须要手动unlock,建议放在finally 代码块中
}
}
public void awaitB(){
try {
lock.lock();
System.out.println("begin awaitB时间为"+System.currentTimeMillis()
+"ThreadName="+Thread.currentThread().getName());
conditionB.await();
System.out.println("end awaitB 时间为"+System.currentTimeMillis()
+"ThreadName"+Thread.currentThread().getName());
}catch (InterruptedException e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void signalAll_A(){
try {
lock.lock();
System.out.println("signalAll_A时间为"+System.currentTimeMillis()
+"ThreadName"+ Thread.currentThread().getName());
conditionA.signalAll();
}finally {
lock.unlock();
}
}
public void signalAll_B(){
try {
lock.lock();
System.out.println("signalAll_B时间为"+System.currentTimeMillis()
+"ThreadName"+ Thread.currentThread().getName());
conditionB.signalAll();
}finally {
lock.unlock();
}
}
}
public class ThreadA extends Thread {
private MyService service;
public ThreadA(MyService service){
super();
this.service=service;
}
@Override
public void run(){
service.awaitA();
}
}
public class ThreadB extends Thread {
private MyService service;
public ThreadB(MyService service){
super();
this.service=service;
}
@Override
public void run(){
service.awaitB();
}
}
public class test {
public static void main(String args[]){
MyService service=new MyService();
ThreadA a=new ThreadA(service);
a.setName("A");
ThreadB b=new ThreadB(service);
b.setName("B");
a.start();
b.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
service.signalAll_A();
}
}
资料整理来自:https://blog.csdn.net/awille/article/details/81869380