(事先声明:该文章并非完全是我自己的产出,更多的是我个人在看到资料后通过理解并记录下来,作为自己阅读后的一个笔记;我现在试图对自己多年工作中的知识点做一个回顾,并进行归类总结)
(此文参考<Java核心技术36讲>第17讲)
线程与进程
进程是操作系统层面的运行时对应的具体应用程序,用户启动一个应用程序就会运行一个或者多个进程。
线程是应用程序进程里面的,更加细粒度的实例,线程对用户而言是透明的,一个进程会包含一个或者多线程来实现程序的各种功能。其由开发人员在编写代码时定义,并由系统进行调度运行。
在早期的JVM设计中 (1.2),线程的实现是与虚拟机相关的,且于JVM自身来调度(Green thread),在现在的版本中, java线程基本都是1对1映射到操作系统内核线程了,由OS进行调度。
还有一种后台运行的称为守护线程, 当应用需要一个长期驻留的服务程序,但不希望其影响应用退出,就可以设置为守护线程;JVM发现只有守护线程存在时,进程结束。
线程包含什么
从操作系统的角度,线程是系统调试的最小单元,操作系统对不同任务的切换,就是在线程上完成的,线程包含: 栈(Stack), 寄存器(Register),本地存储(Thread Local)。但其和进程内其它线程共享文件描述符,虚拟地址空间等。
(补充: 更详细的线程结构和jvm内部)
线程生命周期的不同状态:
New: 线程被新建出来还没有真正启动执行。
Runnable(就绪): 表示线程已经在JVM中执行了,可能是正在运行,也可能是在等待CPU调度。
Blocked(阻塞): 表示线程在等待锁,如:线程试图通过synchronized去获取某个锁时,该锁已经被其它线程独占了,那当前线程就会进入此状态。
WAITING: 线程进行等待状态,需要其它线程唤醒(notify),如:当前线程在检测到需要的资源还不可用时,主动执行wait()。
TIMED_WAIT: 与上面相似,但带有超时条件。
Terminated: 终止,不管是意外退出还是正常执行结束。
线程的几种使用
1. 直接继承自Thread并且实现任务执行
public void startNewThread() { new Thread(() -> { // excute task, we override the method Thread.run() }).start(); //start the thread }
2. 实现Runnable
实现Runnable接口的好处在于可以绕过java只能单一继承的限制(使用Thread的话,就不能继承其它类了), 这样可以更灵活的组织代码结构了。也可以把Runnable提交给并发库中的Executor框架使用。
Runnable task = new Runnable() { @Override public void run() { // implement the task } }; new Thread(task).start(); //start the thread
3.使用Executor框架
可以无须关心Thread的创建和管理,并且可以通Future来取得返回结果.
Runnable task = new Runnable() { @Override public void run() { // implement the task } }; Future result = Executors.newFixedThreadPool(1).submit(task);

浙公网安备 33010602011771号