【杂记】高并发的几种设计模式

1.高并发的场景下的你都用过哪些设计模式?

线程安全的单例模式、ForkJoin模式、生产者-消费者模式、Master-Worker模式和Future模式。

2.简单介绍一下线程安全的单例模式?

单例模式是一种常见的设计模式,一般用于安全对象管理,比如XML读写实例、系统配置实例、任务调度实例、数据库连接池实例等。单例模式一般分为懒汉式、饿汉式。饿汉式单例在类加载时候,就直接初始化。懒汉式,就是在类使用的时候,才对单例进行初始化。

3.饿汉式的优缺点?

饿汉单例模式的优点是足够简单、安全。其缺点是:单例对象在类被加载时,实例就直接被初始化了。很多时候,在类被加载时并不需要进行单例初始化,所以需要对单例的初始化予以延迟,一直到实例使用的时候初始化。

4.多线程下如何确保懒汉式足够的安全?

(1)使用内置锁保护懒汉式单例
(2)双重检查锁单例模式,可以先判断单例对象是否已经被初始化,如果没有,加锁后再初始化,这种模式被叫作双重检查锁(Double Checked Locking)单例模式。
(3)静态内部类实现懒汉式单例,使用静态内部类实现懒汉式单例模式只有在getInstance()被调用时才去加载内部类并且初始化单例,该方式既解决了线程安全问题,又解决了写法烦琐问题。

5.Master-Worker设计模式是什么?

Master-Worker它的核心思想是任务的调度和执行分离,调度任务的角色为Master,执行任务的角色为Worker,Master负责接收、分配任务和合并任务结果集,worker负责执行任务。Master-worker模式是一种归并类型的模式。

6.nginx中是如何应用master-worker的设计思想的?

Nginx的Master进程主要负责调度Worker进程,比如加载配置、启动工作进程、接收来自外界的信号、向各Worker进程发送信号、监控Worker进程的运行状态等。Master进程负责创建监听套接口,交由Worker进程进行连接监听。Worker进程主要用来处理网络事件,当一个Worker进程在接收一条连接通道之后,就开始读取请求、解析请求、处理请求,处理完成产生的数据后,再返回给客户端,最后断开连接通道。

7.ForkJoin模式是什么?

forkjoin模式也是一种分而治之思想的另一种应用,与master-worker模式不同的是,forkjoin没有master角色,其所有的角色都是worker,ForkJoin模式中的Worker将大的任务分割成小的任务,一直到任务的规模足够小,可以使用很简单、直接的方式来完成。ForkJoin模式先把一个大任务分解成许多个独立的子任务,然后开启多个线程并行去处理这些子任务。有可能子任务还是很大而需要进一步分解,最终得到足够小的任务。

8.Forjoin里面采用的算法是什么?

工作窃取算法的核心思想是:工作线程自己的活干完了之后,会去看看别人有没有没干完的活,如果有就拿过来帮忙干。工作窃取算法的主要逻辑:每个线程拥有一个双端队列(本地队列),用于存放需要执行的任务,当自己的队列没有任务时,可以从其他线程的任务队列中获得一个任务继续执行,其优点有(1)线程是不会因为等待某个子任务的执行或者没有内部任务要执行而被阻塞等待、挂起的,而是会扫描所有的队列窃取任务,直到所有队列都为空时才会被挂起。(2)ForkJoin框架为每个线程维护着一个内部任务队列以及一个全局的任务队列,而且任务队列都是双向队列,可从首尾两端来获取任务,极大地减少了竞争的可能性,提高并行的性能。

9.Forjoin框架的原理是什么?

(1)ForkJoin框架的线程池ForkJoinPool的任务分为“外部任务”和“内部任务”。
(2)“外部任务”放在ForkJoinPool的全局队列中。
(3)ForkJoinPool池中的每个线程都维护着一个任务队列,用于存放“内部任务”,线程切割任务得到的子任务会作为“内部任务”放到内部队列中。
(4)当工作线程想要拿到子任务的计算结果时,先判断子任务有没有完成,如果没有完成,再判断子任务有没有被其他线程“窃取”,如果子任务没有被窃取,就由本线程来完成;一旦子任务被窃取了,就去执行本线程“内部队列”的其他任务,或者扫描其他的任务队列并窃取任务。
(5)当工作线程完成其“内部任务”,处于空闲状态时,就会扫描其他的任务队列窃取任务,尽可能不会阻塞等待。

你可能感兴趣的:(杂记,设计模式,单例模式,java)