进程就是运行着的程序,是动态的。线程则是基本执行单位,一个进程可以产生多个线程,线程拥有自己的程序计数器pc、虚拟机栈、本地方法栈,同时共享着进程的堆和方法区。切换线程的负担比切换进程的负担小,因此线程又被成为轻量级进程。
线程模型
线程模型是用户线程和内核线程之间的关联方式
- 一对一(一个用户线程对应一个内核线程)
- 多对一(多个用户线程映射到一个内核线程)
- 多对多(多个用户线程映射到多个内核线程)
线程模型
进程与线程之间的对比
进程 | 线程 | |
定义 | 资源分配的基本单位 | 程序执行的最小单位 |
是否独立 | 各进程独立 | 各线程间极有可能会相互影响 |
线程的程序计数器为什么是私有的?
程序计数器私有主要是为了线程切换后能恢复到正确的执行位置。
线程的虚拟机栈和本地方法栈为什么是私有的?
为了保证线程执行方法时局部变量不被别的线程访问到。
并行与并发
并发:多个作业在同一时间段内一起执行
并行:多个作业在同一时刻一起执行
同步与异步
同步:发出一个调用之后,在没有得到结果之前, 该调用就不可以返回,一直等待。
异步:调用在发出之后,不用等待返回结果,该调用直接返回。
使用多线程的好处?
1. 线程间的切换和调度的成本远远小于进程。
2. 可以大大提高系统整体的并发能力以及性能。
3. 提高了 Java 进程利用系统资源的整体效率。(单核CPU)
4. 在任务中的多个线程没有资源竞争的情况下,任务执行的效率会有显著性的提高(多核CPU)
使用多线程的坏处?
并发编程并不总是能提高程序运行速度,而且还可能导致内存泄漏、死锁、线程不安全等问题
注意:在单核 CPU 上,如果线程是 CPU 密集型的,那么多个线程同时运行会导致频繁的线程切换,增加了系统的开销,降低了效率。如果线程是 IO 密集型的,那么多个线程同时运行可以利用 CPU 在等待 IO 时的空闲时间,提高了效率,所以并发编程并不总是能提高程序运行速度。
wait()方法和sleep()方法对比
sleep | wait | |
调用时是否释放锁 | 否 | 是 |
是否自动苏醒 | 是 | 否 |
用途 | 暂停执行线程 | 线程间交互 |
方法 | Thread类的静态本地方法 | Object类的本地方法 |
可以直接调用 Thread 类的 run 方法吗?
调用 start()
方法方可启动线程并使线程进入就绪状态,当分配到时间片后自动执行 run()
方法的内容,这是多线程工作。直接执行 run()
方法,会把 run()
方法当成一个 main 线程下的普通方法去执行,不会以多线程的方式执行。