基础知识
1、进程和线程
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源。
线程是程序执行的最小单位,它是进程的一个执行流,是CPU调度和分配的最小单位,一个进程可以由很多线程组成,线程间共享进程的所有资源。
2、并发与并行
并发:在操作系统中,某一时间段,几个程序在同一个CPU上运行,但在任意一个时间点上,只有一个在CPU上运行
并行:当操作系统有多个CPU时,一个CPU处理A线程,另一个CPU处理B线程,两个线程互相不抢占CPU资源,可以同时进行,这种方式称为并行
3、阻塞
阻塞是指调用结果返回之前,当前线程会被操作系统挂起。调用线程只有在得到结果之后才会返回。
4、同步与异步
所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回
异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果
5、JAVA 创建线程的方式(jdk官方文档只有两种)
继承Thread类创建
实现Runnable接口创建线程
其它的非官方的
使用Callable 和 Future创建线程
使用线程池例如用Executor框架
6、wait()和sleep()的区别
sleep 是线程中方法,但是wait是Objet中的方法
sleep方法不会释放lock,但是wait会释放、而且会加入到等待队列中
sleep 方法不依赖于同步器synchroized,但是wait需要依赖synchroized关键字
sleep 不需要被唤醒(休眠之后推出阻塞),但是wait需要
7、线程生命周期(状态)
当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Runing)、阻塞(Blocked)和死亡(Dead)5中状态。尤其是当线程启动以后,它不可能一直“”霸占“着CPU独自运行,所以CPU需要再多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换
新建状态(NEW)
当程序使用new 关键字创建了一个线程之后,该线程就处于新建状态,此时仅由JVM为其分配内存,并初始化其成员变量值
就绪状态(RUNNABLE)
当线程对象调用了start()方法之后,该线程处于就绪状态。Java 虚拟机会为其创建方法调用栈和程序计数器,等待调度运行
运行状态(RUNNING)
如果处于就绪状态的线程获得了CPU,开始执行run()方法的线程执行体,则线程处于运行状态
阻塞状态(BLOCKED):
阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cpu timeslice,暂时停止运行,才有机会再次获得cpu timeslie 转到运行(running)状态、阻塞的情况分为三种:
等待阻塞(o.wait>等待队列):
运行(running)的线程执行 o.wait()方法,JVM 会把该线程放入等待队列(waiting queue)中。
同步阻塞(lock>锁池)
运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中
其他阻塞(sleep/join)
运行(running)的线程执行Thread.sleep(long ms)或 t.join()方法,或者发出了I/0请求时,JVM 会把该线程置为阻塞状态。当sleep()状态超时,join()等待线程终止或者超时时、或者I/0处理完毕时,线程重新转入可运行(runnable)状态
死亡状态(DEAD)
线程会以下面三种方式结束、结束后就是死亡状态
正常结束
1、run() 或call()方法执行完成,线程正常结束
异常结束
2、线程抛出一个未捕获的Exception 或Error
调用stop
3、直接调用该线程的stop() 方法来结束该线程---该方法通常容易导致死锁,不推荐使用