设计模式 - 图1

生产者与消费者模式

生产者生产数据存放到 缓存区 ,消费者从缓存区读取数据,缓存区要求是阻塞队列
为了解决:多线程同步问题
优点:

  1. 支持生产\消费忙闲不均
  2. 解耦 ,生产与消费不直接通信
  3. 支持并发

    java能实现的几种模式

    保证同一资源被多个线程并发访问时的完整性。常用的同步方法是采用信号或加锁机制,保证资源在任意时刻至多被一个线程访问。

  4. wait()/notify() 方法

  5. await()/signal()方法
  6. BlockingQueue 阻塞队列
  7. 信号量
  8. 管道

    4:信号量

    Semaphore是一种基于计数的信号量。它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做完自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞。Semaphore可以用来构建一些对象池,资源池之类的,比如数据库连接池,我们也可以创建计数为1的Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量,表示两种互斥状态。计数为0的Semaphore是可以release的,然后就可以acquire(即一开始使线程阻塞从而完成其他执行。)。 ```javascript import java.util.LinkedList; import java.util.concurrent.Semaphore;

public class Storage {

  1. // 仓库存储的载体
  2. private LinkedList<Object> list = new LinkedList<Object>();
  3. // 仓库的最大容量
  4. final Semaphore notFull = new Semaphore(10);
  5. // 将线程挂起,等待其他来触发
  6. final Semaphore notEmpty = new Semaphore(0);
  7. // 互斥锁
  8. final Semaphore mutex = new Semaphore(1);
  9. public void produce()
  10. {
  11. try {
  12. notFull.acquire();
  13. mutex.acquire();
  14. list.add(new Object());
  15. System.out.println("【生产者" + Thread.currentThread().getName()
  16. + "】生产一个产品,现库存" + list.size());
  17. }
  18. catch (Exception e) {
  19. e.printStackTrace();
  20. } finally {
  21. mutex.release();
  22. notEmpty.release();
  23. }
  24. }
  25. public void consume()
  26. {
  27. try {
  28. notEmpty.acquire();
  29. mutex.acquire();
  30. list.remove();
  31. System.out.println("【消费者" + Thread.currentThread().getName()
  32. + "】消费一个产品,现库存" + list.size());
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. } finally {
  36. mutex.release();
  37. notFull.release();
  38. }
  39. }

}

  1. <a name="L61Ys"></a>
  2. ## 责任链模式
  3. 将串行执行的业务流程,抽象为类,多个类**链**起来,暴露一个方法来执行**链**上的方法<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)
  4. ```java
  5. public interface Filter {
  6. // 过滤
  7. void doFilter(String data);
  8. }
  9. class FilterEgg implements Filter {
  10. @Override
  11. public void doFilter(String data) {
  12. //doSomething
  13. }
  14. }
  15. class FilterAoBing implements Filter {
  16. @Override
  17. public void doFilter(String data) {
  18. //doSomething
  19. }
  20. }
  21. class FilterBaiCai implements Filter {
  22. @Override
  23. public void doFilter(String data) {
  24. //doSomething
  25. }
  26. }
  27. class FilterJiTou implements Filter {
  28. @Override
  29. public void doFilter(String data) {
  30. //doSomething
  31. }
  32. }
  1. // 抽象对外暴露一个接口
  2. public class FilterChain {
  3. List<Filter> filters = new ArrayList<>();
  4. public FilterChain() {
  5. filters.add(new FilterEgg());
  6. filters.add(new FilterAoBing());
  7. filters.add(new FilterBaiCai());
  8. filters.add(new FilterJiTou());
  9. }
  10. public void processData(String data) {
  11. for (Filter filter : filters) {
  12. filter.doFilter(data);
  13. }
  14. }
  15. }

模板模式

封装不变的部分,扩展可变的部分

  1. // 通用模板
  2. public abstract class WriteArticle {
  3. // 每个人的“前言”都不一样,所以抽象(abstract)
  4. protected abstract void introduction();
  5. // 每个人的“最后”都不一样,所以抽象(abstract)
  6. protected abstract void theLast();
  7. // 实际要写的内容,每个人的“实际内容”都不一样,所以抽象(abstract)
  8. protected abstract void actualContent();
  9. // 写一篇完整的文章(为了方便调用,我们将这几个步骤分装成一个方法)
  10. public final void writeAnCompleteArticle() {
  11. // 前言
  12. introduction();
  13. // 实际内容
  14. actualContent();
  15. // 最后
  16. theLast();
  17. }
  18. }