首先我要记录一下锁的相关知识点:
x可以是this也可以是非this
-
当多个线程同时执行synchronized(x){}同步代码块时呈同步效果
-
当其它线程执行x对象中synchronized同步方法时呈同步效果
-
当其它线程执行x对象方法里面的synchronized(this)代码块时也呈同步效果。
如果其它线程调用x对象里的非synchronized方法时,还是呈异步效果。 -
synchronized修饰static静态方法时,是对当前*.java文件对应的Class类持锁。对象锁和class锁不是同一把锁。
-
Class锁可以对类的所有对象实例起作用。
-
String作为非this锁时,因为String常量池功能,所以如果字符串相同的话,导致持有的是同一把锁。
生产者消费者
package com.reentrant;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Person {
static int aaa = 5;
private int maxStoreSize = 10;
private int grapesCount = 0;
private int bananasCount = 0;
private Lock lock = new ReentrantLock();
private Condition conditionGrape = lock.newCondition();
private Condition conditionBanana = lock.newCondition();
public void yieldGrapes() {
lock.lock();
if(grapesCount==maxStoreSize){
try {
conditionGrape.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
grapesCount++;
System.out.println(Thread.currentThread().getName()+"生产一个葡萄"+",库存葡萄总数量:"+grapesCount);
conditionGrape.signalAll();
lock.unlock();
}
public void yieldBananas() {
lock.lock();
if(bananasCount==maxStoreSize){
try {
conditionBanana.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
bananasCount++;
System.out.println(Thread.currentThread().getName()+"生产一个香蕉"+",库存香蕉总数量:"+bananasCount);
conditionBanana.signalAll();
lock.unlock();
}
public void consumeGrapes() {
lock.lock();
if(grapesCount==0){
try {
conditionGrape.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
grapesCount--;
System.out.println(Thread.currentThread().getName()+"消费一个葡萄"+",库存葡萄总数量:"+grapesCount);
if(grapesCount<=0){
conditionGrape.signalAll();
}
lock.unlock();
}
public void consumeBananas() {
lock.lock();
if(bananasCount==0){
try {
conditionBanana.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
bananasCount--;
System.out.println(Thread.currentThread().getName()+"消费一个香蕉"+",库存香蕉总数量:"+bananasCount);
if(bananasCount<=0){
conditionBanana.signalAll();
}
lock.unlock();
}
public static void main(String[] args) throws InterruptedException {
Person p = new Person();
Runnable yieldGrapes = ()->{
for(int i = 0;i<Person.aaa;i++){
p.yieldGrapes();
}
};
Runnable yieldBananas = ()->{
for(int i = 0;i<Person.aaa;i++){
p.yieldBananas();
}
};
Runnable consumeGrapes = ()->{
for(int i = 0;i<Person.aaa;i++){
p.consumeGrapes();
}
};
Runnable consumeBananas = ()->{
for(int i = 0;i<Person.aaa;i++){
p.consumeBananas();
}
};
Thread t1 = new Thread(yieldGrapes,"【秦孝公】");
Thread t2 = new Thread(yieldBananas,"【秦惠文王】");
Thread t3 = new Thread(consumeGrapes,"【秦昭襄王】");
Thread t4 = new Thread(consumeBananas,"【秦始皇】");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
Condition可以唤醒部分指定线程。