进程和线程
进程是程序执行的过程,进程是线程的容器,一个进程包含多个线程
线程是一个指令流,就是一条条指令交给cpu执行
并发和并行
并行是指多个cpu分别分配给多个线程时间片使各个线程真正的并行执行,线程之间互不干扰
并发是多个线程同一时间竞争同一个cpu时间片
线程的上下文切换
1、线程调用了阻塞的方法
2、 垃圾回收
3、cpu分配的时间片用完
4、有更高优先级的线程运行
线程5大状态
从操作系统层面来说:
初始状态
可运行状态
运行状态
阻塞状态
终止状态
线程6大状态
从java api层面来说:
new:刚被创建
runnable:可运行状态
blocked:阻塞
waiting:阻塞
timed waiting:阻塞
terminated:终结
sleep()
1.使线程从running状态变成timed_wating状态
2.可由别的线程用interrupt方法打断阻塞,会抛出interruptexception,打断后的线程处于唤醒状态
3.结束睡眠或者被唤醒的线程不一定会立即执行,得等都cpu分配时间片后才执行
4.可用timeunit类来调用sleep更好
yeald()
1、让线程从running状态变为runnable状态
2、调用了yield的线程会让出cpu时间片,但不一定不执行,决定与cup任务调度
3、当cpu紧张竞争激烈时还是能有一定作用的
setPriority()
线程优先级:优先级高的线程会得到更多的cpu时间片
join()
等待调用的线程运行结束后执行
join(time),最多等待多长时间,超过时间就不等了
join的阻塞底层原理是wait
park()和unpark()
park表示阻塞自己线程
unpark释放某个线程
1、可以先执行unpark,表示下次调用park时不会被阻塞
2、调用一次park,unpark后可以再次park
3、park可以被打断,打断后,打断标记为真,就像打断正常线程一样
4、park是掉用底层unsafe的park'方法,通常用来执行AQS:AbstractQueuedSynchronizer中的操作
interrupt()
1、打断线程为调用了sleep,wait,join方法时,抛出异常,但是打断标记会重置为false.
2、打断正常运行的线程时,被打断的线程仍会继续执行,打断标记为true
3、isInterrupted()方法可以判断一个线程是否被打断过,通常用于线程决定是否继续运行还是终止线程的逻辑,优雅停止
4、两阶段终止:第一阶段,t1线程向t2发出停止指令;第二阶段,t2线程响应指令终止程序
过时方法
stop,停止线程,resume,唤醒线程,suspend,挂起(暂停)线程运行,容易造成线程死锁
守护线程
1、setDaemon()方法可以设置线程为守护线程
2、别的非守护线程结束后,守护线程不管有没有执行完毕都强制结束。
3、垃圾回收线程为守护线程
4、tomcat种Acceptor和poller线程都是守护线程,当tomcat执行shutdown命令时,别的线程执行完毕不会等待它们处理完当前请求
wait和notify
1、wait:需要和synchronized配合使用,调用obj.wait时进入waiting状体,并释放掉锁,让别的线程获得锁
2、notify:obj.notity(),唤醒wait_set中的一个阻塞的线程,进入entry_list中重新竞争锁
3、notifyAll:唤醒所有wait_set中的线程,同时到entry_list中竞争锁
4、以上方法都必须要获得obj的对象锁,成为owner后才能调用方法