文章字数:872,阅读全文大约需要3分钟
整理自聊聊高并发(二)结合实例说说线程封闭和背后的设计思想
高并发问题简述
定义
: 来自《java并发变成实战》的定义。线程安全指的是多个线程访问某个类时,这个类始终能表现正确行为。
1 2 3 4
| 我的理解是线程安全问题就是多个线程同时操作一个数据, 导致每个线程在读取并操作期间数据可能会被其它线程篡改, 即不能表现正确行为。 而栈空间(方法栈)的数据是线程私有的,所以只有类有这个问题。
|
思路
: 线程安全问题,就是对象状态问题。如果对象无状态(不变性,操作前后一样。),或者避免多个线程共享,那就是线程安全的。只有对象不可避免要被多个线程操作时才会有多线程问题。所以业务代码尽量做到无状态。
1 2 3 4
| 思考流程 1. 能否做成无状态的不变对象 2. 能否线程封闭,不让其他线程操作 3. 实在需要多线程操作,那么采用什么同步技术
|
线程封闭技术
栈封闭
: 多使用局部变量,局部变量属于方法,方法属于栈,栈属于本线程。
ThreadLocal
: 限制其他线程访问的全局变量。本质是一个Map,每个线程只能操作自己作为key下的值。
程序控制线程封闭
: 思想,把处理对象状态的代码放到一个线程中。例子:Netty
,EventLoop
被设计成一个线程池(工作线程+任务队列)。请求被插入任务队列,工作线程再一个个取。这样保证了请求有序处理。
1 2 3
| 思路: 1. 把用户状态相关代码放到一个队列中,由一个线程处理。 2. 考虑是否隔离用户之间状态,及一个用户一个任务队列还是多个用户使用一个。
|
一般设计
1 2 3 4
| 1. 有界任务队列和不限个数的工作线程,任务队列有界保证不会内存被一直加入的请求撑爆。不限个数的工作线程保证任务队列的请求都能被相应,而不至于以为工作线程的速度慢而产生积压。 2. 线程请求尽量快,尽量不超过100ms 3. 单线程处理时间由于任务大而耗时可以拆解成小任务多次执行 4. 小任务还是慢则可以使用线程,异步处理,然后使用线程定时查看状态或者回调函数的形式。
|