java除了jvm自带的synchronized锁,还有java并发包
java.util.concurrent.locks中的ReetrantLock。
ReentrantLock与Synchronized锁区别。
相同点:
两个锁都是悲观锁,可重入锁。
不同点:
synchronized是java原生关键字,基于jvm;ReetrantLock是对象锁,依赖java对象。
synchronized由jvm自动加锁和释放,ReetrantLock需要通过lock、unlock手动释放。
synchronized是非公平锁,ReetrantLock可以通过参数控制公平与非公平。
synchronized只能随机唤醒一个线程或者唤醒所有线程,但是ReetrantLock可以通过Condition精准唤醒线程。
synchronized是不可中断的,除非程序异常,但是ReetrantLock可以中断,通过lock.lockInterruptibly()。
在synchronized优化以前,synchronized的性能比ReenTrantLock差很多,但自jdk1.6版本,synchronized引入了偏向锁,轻量级锁(自旋锁)后,两者的性能就差不多了。
@Slf4j
public class ThreadCommunicate {
//线程可感知公共变量
volatile int index = 0;
ReentrantLock lock =new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
private void printABC3() {
ThreadCommunicate threadCommunicate = new ThreadCommunicate();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
try {
threadCommunicate.printA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
try {
threadCommunicate.printB();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread threadC = new Thread(new Runnable() {
@Override
public void run() {
try {
threadCommunicate.printC();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
threadA.start();
threadB.start();
threadC.start();
}
/**
* lock锁与synchronized锁效果一样
*/
public void printA() throws InterruptedException {
lock.lock();
try {
int num=0;
while(num<=9){
if(index!=0){
conditionA.await();
}
log.info("----A----");
num++;
index=1;
conditionB.signal();
}
}finally {
lock.unlock();
}
}
public void printB() throws InterruptedException {
lock.lock();
try {
int num=0;
while(num<=9){
if(index!=1){
conditionB.await();
}
log.info("----B----");
num++;
index=2;
conditionC.signal();
}
}finally {
lock.unlock();
}
}
public void printC() throws InterruptedException {
lock.lock();
try {
int num=0;
while(num<=9){
if(index!=2){
conditionC.await();
}
log.info("----C----");
num++;
index=0;
conditionA.signal();
}
}finally {
lock.unlock();
}
}
}