0%

线程封闭背后设计思想

文章字数:872,阅读全文大约需要3分钟

整理自聊聊高并发(二)结合实例说说线程封闭和背后的设计思想

高并发问题简述

  1. 定义: 来自《java并发变成实战》的定义。线程安全指的是多个线程访问某个类时,这个类始终能表现正确行为。
1
2
3
4
我的理解是线程安全问题就是多个线程同时操作一个数据,
导致每个线程在读取并操作期间数据可能会被其它线程篡改,
即不能表现正确行为。
而栈空间(方法栈)的数据是线程私有的,所以只有类有这个问题。
  1. 思路: 线程安全问题,就是对象状态问题。如果对象无状态(不变性,操作前后一样。),或者避免多个线程共享,那就是线程安全的。只有对象不可避免要被多个线程操作时才会有多线程问题。所以业务代码尽量做到无状态。
1
2
3
4
思考流程
1. 能否做成无状态的不变对象
2. 能否线程封闭,不让其他线程操作
3. 实在需要多线程操作,那么采用什么同步技术

线程封闭技术

  1. 栈封闭: 多使用局部变量,局部变量属于方法,方法属于栈,栈属于本线程。
  2. ThreadLocal: 限制其他线程访问的全局变量。本质是一个Map,每个线程只能操作自己作为key下的值。
  3. 程序控制线程封闭: 思想,把处理对象状态的代码放到一个线程中。例子:NettyEventLoop被设计成一个线程池(工作线程+任务队列)。请求被插入任务队列,工作线程再一个个取。这样保证了请求有序处理。
1
2
3
思路:
1. 把用户状态相关代码放到一个队列中,由一个线程处理。
2. 考虑是否隔离用户之间状态,及一个用户一个任务队列还是多个用户使用一个。

一般设计

1
2
3
4
1. 有界任务队列和不限个数的工作线程,任务队列有界保证不会内存被一直加入的请求撑爆。不限个数的工作线程保证任务队列的请求都能被相应,而不至于以为工作线程的速度慢而产生积压。
2. 线程请求尽量快,尽量不超过100ms
3. 单线程处理时间由于任务大而耗时可以拆解成小任务多次执行
4. 小任务还是慢则可以使用线程,异步处理,然后使用线程定时查看状态或者回调函数的形式。