jdk1.5之后的lock对象的使用(生产以及消费包子案例)
各位大佬们,这是首次发布自己的一些见解,说的不足之处,还望见谅,小菜鸟一枚,请指教!!!
jdk1.5之后的lock的子类ReentrantLock,可以根据newCondition()方法单独生成不同的condition对象,然后这个监视器对象可以通过awati()方法让线程陷入等待的阻塞状态,并且只有同一个condition(监视器对象)才能将其唤醒,原来的notifyall()方法是无法将其唤醒的, 说白了就是ReentrantLock,就是可以为我们创造多个监视器对象,对不同的线程做到更加细致的控制,监视;
下面是我自己写的案例,可以参考下:
<!--这里是maven项目用到的jar包..-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
这是生产者包子铺
import com.xwd.utils.XwdUtils;
import lombok.Data;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author xwd
* @version 1.0
*/
@Data
public class BaoZiPu implements Runnable {
private List<Integer> baoziList;
private int serializeNum = 0;
private ReentrantLock reentrantLock ;
private Condition product ;
private Condition consume ;
public BaoZiPu(List<Integer> baoziList, ReentrantLock reentrantLock, Condition product, Condition consume) {
this.baoziList = baoziList;
this.reentrantLock = reentrantLock;
this.product = product;
this.consume = consume;
}
@Override
public void run() {
while (true) {
reentrantLock.lock();
try {
if (baoziList.size() <= 0) {
//自己生产之前,先唤醒其他的线程;
baoziList.add((++serializeNum));
System.out.println(XwdUtils.getCurrentThreadName() + "生产了" + serializeNum + "号包子...");
XwdUtils.watiXwd(500L);
//陷入沉睡之前要唤醒消费者啊...
consume.signal();
//使用自己的监视器对象,
try {
product.await();
} catch (Exception e) {
e.printStackTrace();
}
}
} finally {
reentrantLock.unlock();
}
}
}
}
这是消费者
import com.sun.media.sound.RIFFInvalidDataException;
import com.xwd.utils.XwdUtils;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author xwd
* @version 1.0
*/
@Data
public class XiaoFeiZhe implements Runnable {
private List<Integer> baoziList;
private Condition product;
private Condition consume;
private ReentrantLock reentrantLock;
public XiaoFeiZhe(List<Integer> baoziList, Condition product, Condition consume, ReentrantLock reentrantLock) {
this.baoziList = baoziList;
this.product = product;
this.consume = consume;
this.reentrantLock = reentrantLock;
}
@Override
public void run() {
while (true) {
if (baoziList.size() > 0) {
reentrantLock.lock();
baoziList.forEach(integer -> System.out.println(XwdUtils.getCurrentThreadName() + "消费了" + integer + "号包子.."));
XwdUtils.watiXwd(500L);
//消费完所有的集合
baoziList.clear();
try {
//唤醒生产者生产...
product.signal();
//消费完就睡觉
consume.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
}
}
}
}
这是Demo案例
import com.xwd.entity.BaoZiPu;
import com.xwd.entity.XiaoFeiZhe;
import com.xwd.utils.XwdUtils;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author xwd
* @version 1.0
*/
public class ThradDemoTest {
//创建出锁
ReentrantLock reentrantLock = new ReentrantLock();
//再根据锁创建出专属负责生产者的监视器对象
Condition product = reentrantLock.newCondition();
//再根据锁创建出专属负责消费者者的监视器对象
Condition consume = reentrantLock.newCondition();
ExecutorService threadPool = Executors.newFixedThreadPool(4);
@Test
public void test01() {
//创建存储包子的集合,容器
List<Integer> list = new ArrayList<>();
//创建生产者的生产包子任务
BaoZiPu baoZiPu = new BaoZiPu(list, reentrantLock, product, consume);
threadPool.submit(baoZiPu);
threadPool.submit(baoZiPu);
//创建消费者者的消费包子任务
XiaoFeiZhe xiaoFeiZhe = new XiaoFeiZhe(list, product, consume, reentrantLock);
threadPool.submit(xiaoFeiZhe);
threadPool.submit(xiaoFeiZhe);
//这里没啥意思,就是单纯的让主线程,等待10分钟...
XwdUtils.watiXwd(100000L);
}
}