生产者与消费者模式
生产者生产数据存放到 缓存区 ,消费者从缓存区读取数据,缓存区要求是阻塞队列
为了解决:多线程同步问题
优点:
- 支持生产\消费忙闲不均
- 解耦 ,生产与消费不直接通信
-
java能实现的几种模式
保证同一资源被多个线程并发访问时的完整性。常用的同步方法是采用信号或加锁机制,保证资源在任意时刻至多被一个线程访问。
wait()/notify() 方法
- await()/signal()方法
- BlockingQueue 阻塞队列
- 信号量
- 管道
4:信号量
Semaphore是一种基于计数的信号量。它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做完自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞。Semaphore可以用来构建一些对象池,资源池之类的,比如数据库连接池,我们也可以创建计数为1的Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量,表示两种互斥状态。计数为0的Semaphore是可以release的,然后就可以acquire(即一开始使线程阻塞从而完成其他执行。)。 ```javascript import java.util.LinkedList; import java.util.concurrent.Semaphore;
public class Storage {
// 仓库存储的载体
private LinkedList<Object> list = new LinkedList<Object>();
// 仓库的最大容量
final Semaphore notFull = new Semaphore(10);
// 将线程挂起,等待其他来触发
final Semaphore notEmpty = new Semaphore(0);
// 互斥锁
final Semaphore mutex = new Semaphore(1);
public void produce()
{
try {
notFull.acquire();
mutex.acquire();
list.add(new Object());
System.out.println("【生产者" + Thread.currentThread().getName()
+ "】生产一个产品,现库存" + list.size());
}
catch (Exception e) {
e.printStackTrace();
} finally {
mutex.release();
notEmpty.release();
}
}
public void consume()
{
try {
notEmpty.acquire();
mutex.acquire();
list.remove();
System.out.println("【消费者" + Thread.currentThread().getName()
+ "】消费一个产品,现库存" + list.size());
} catch (Exception e) {
e.printStackTrace();
} finally {
mutex.release();
notFull.release();
}
}
}
<a name="L61Ys"></a>
## 责任链模式
将串行执行的业务流程,抽象为类,多个类**链**起来,暴露一个方法来执行**链**上的方法<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/12671612/1648783469096-3062c564-19af-4f2c-87bb-68ceab78bcde.png#clientId=ucc806ac5-ed6c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=555&id=u8a13587a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=555&originWidth=685&originalType=binary&ratio=1&rotation=0&showTitle=false&size=428534&status=done&style=none&taskId=u425cacc8-6bc1-496e-9b1e-9636c1e908e&title=&width=685)
```java
public interface Filter {
// 过滤
void doFilter(String data);
}
class FilterEgg implements Filter {
@Override
public void doFilter(String data) {
//doSomething
}
}
class FilterAoBing implements Filter {
@Override
public void doFilter(String data) {
//doSomething
}
}
class FilterBaiCai implements Filter {
@Override
public void doFilter(String data) {
//doSomething
}
}
class FilterJiTou implements Filter {
@Override
public void doFilter(String data) {
//doSomething
}
}
// 抽象对外暴露一个接口
public class FilterChain {
List<Filter> filters = new ArrayList<>();
public FilterChain() {
filters.add(new FilterEgg());
filters.add(new FilterAoBing());
filters.add(new FilterBaiCai());
filters.add(new FilterJiTou());
}
public void processData(String data) {
for (Filter filter : filters) {
filter.doFilter(data);
}
}
}
模板模式
封装不变的部分,扩展可变的部分
// 通用模板
public abstract class WriteArticle {
// 每个人的“前言”都不一样,所以抽象(abstract)
protected abstract void introduction();
// 每个人的“最后”都不一样,所以抽象(abstract)
protected abstract void theLast();
// 实际要写的内容,每个人的“实际内容”都不一样,所以抽象(abstract)
protected abstract void actualContent();
// 写一篇完整的文章(为了方便调用,我们将这几个步骤分装成一个方法)
public final void writeAnCompleteArticle() {
// 前言
introduction();
// 实际内容
actualContent();
// 最后
theLast();
}
}