01-线程基础
1 CPU核心数和线程数
核心数:线程数=1:1
使用了超线程技术后—> 1:2
2 CPU时间片轮转机制
为了实现轮转调度,系统把所有就绪进程按先入先出的原则排成一个队列,新来的进程加到就绪队尾。
每当执行进程调度时,进程调度程序总是选出就绪队列的队首进程,让它在 CPU 上运行一个时间片的时间。
时间片是一个小的时间单位,通常为 10~100ms 数量级。
进程用完时间片后,调度程序便停止该进程的运行,把它放入就绪队列的末尾。然后,把CPU分给就绪队列的队首进程,同样也让它运行一个时间片,如此往复。
会导致上下文切换
3 进程和线程
-
进程
程序运行资源分配的最小单位,进程内部有多个线程,会共享这个进程的资源
-
线程
CPU调度的最小单位,必须依赖进程而存在。
4 并行和并发
-
并行
同一时刻,可以同时处理事情的能力
-
并发
与单位时间相关,在单位时间内可以处理事情的能力
5 高并发的意义和注意事项
- 意义
充分利用cpu的资源、加快用户响应的时间,程序模块化,异步化
- 注意事项
- 线程共享资源,存在冲突
- 容易导致死锁
- 启用太多的线程,就有搞垮机器的可能
6 创建线程的方式
-
类Thread
-
接口Runnacle
-
接口Callable
[注意]Future、FutureTask、CompletionService、CompletableFuture
- Future
取消
获取线程结果
使用状态判断是否取消
使用状态判断是否完成
7 线程停止的方式
java线程是协作式,而非抢占式
-
stop(),resume(),suspend()
已不建议使用,stop()会导致线程不会正确释放资源,suspend()容易导致死锁
-
interrupt()
并不是强行关闭这个线程,只是跟这个线程打个招呼,将线程的中断标志位置为true,线程是否中断,由线程本身决定
-
isInterrupted()
判定当前线程是否处于中断状态
-
static interrupted()
判定当前线程是否处于中断状态,同时中断标志位改为false
-
注意
方法里如果抛出InterruptedException,线程的中断标志位会被复位成false,如果确实是需要中断线程,要求我们自己在catch语句块里再次调用interrupt()。
8 线程的yield()方法
让出cpu的执行权,将线程从运行转到可运行状态,但是下个时间片,该线程依然有可能被再次选中运行。
9 线程的优先级
取值为1~10,缺省为5,但线程的优先级不可靠,不建议作为线程开发时候的手段
10 守护线程
-
User Thread(用户线程)
-
Daemon Thread(守护线程)
1.守护线程并非虚拟机内部可以提供,用户也可以自行的设定守护线程 方法:public final void setDaemon(boolean on) 2.thread.setDaemon(true)必须在thread.start()之前设置 否则会IllegalThreadStateException异常。 3.你不能把正在运行的常规线程设置为守护线程。
11 等待和通知机制
wait()方法,进入等待,notify()/notifyAll()方法,唤醒
notify和notifyAll
应该尽量使用notifyAll,使用notify因为有可能发生信号丢失的的情况
等待方:
1、获取对象的锁;
2、循环里判断条件是否满足,不满足调用wait方法,
3、条件满足执行业务逻辑
通知方来说
1、获取对象的锁;
2、改变条件
3、通知所有等待在对象的线程
-
join()方法
线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程将早于子线程结束。这时,如果主线程想等子线程执行完成才结束,比如子线程处理一个数据,主线程想要获得这个数据中的值,就要用到join()方法了。
作用:
-
等待线程对象销毁。
-
同步,它可以使得线程之间的并行执行变为串行执行。
在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行。
-
12 调用yield() 、sleep()、wait()、notify()等方法对锁有何影响
- 线程在执行yield()以后,持有的锁是不释放的;
- sleep()方法被调用以后,持有的锁是不释放的;
- 调动方法之前,必须要持有锁。调用了wait()方法以后,锁就会被释放,当wait方法返回的时候,线程会重新持有锁;
- 调动方法之前,必须要持有锁,调用notify()方法本身不会释放锁的;
13 QPS、吞吐量、并发数、EPS
- QPS
每秒查询率,对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准
原理:
每天80%的访问集中在20%的时间里,这20%时间叫做峰值时间。
公式:
( 总PV数 * 80% ) / ( 每天秒数 * 20% ) = 峰值时间每秒请求数(QPS) 。
机器:
峰值时间每秒QPS / 单台机器的QPS = 需要的机器 。
每天300w PV 的在单台机器上,这台机器需要多少QPS?
( 3000000 * 0.8 ) / (86400 * 0.2 ) = 139 (QPS)。一般需要达到139QPS,因为是峰值。
- 吞吐量(Throughput)
吞吐量是指系统在单位时间内处理请求的数量。
- 并发用户数
并发用户数是指系统可以同时承载的正常使用系统功能的用户的数量。
- EPS
每秒处理的事件数
17 浏览量(PV)、访客数(UV)、访问次数、跳出率
- 浏览量(PV)
即通常说的Page View(PV),用户每打开一个网站页面就被记录1次。用户多次打开同一页面,浏览量值累计。
- 访客数(UV)
一天之内您网站的独立访客数(以Cookie为依据),一天内同一访客多次访问您网站只计算1个访客。
- 访问次数
访客在您网站上的会话(Session)次数,一次会话过程中可能浏览多个页面。如果访客连续30分钟没有新开和刷新页面,或者访客关闭了浏览器,则当访客下次访问您的网站时,访问次数加1。
- IP数
一天之内您网站的独立访问ip数。
- 新访客数
一天的独立访客中,历史第一次访问您网站的访客数。
- 新访客比率
新访客比率=新访客数/访客数。
- 跳出率
只浏览了一个页面便离开了网站的访问次数占总的访问次数的百分比。
- 平均访问时长
访客在一次访问中,平均打开网站的时长。即每次访问中,打开第一个页面到关闭最后一个页面的平均值,打开一个页面时计算打开关闭的时间差。
- 转化次数
访客到达转化目标页面的次数。