- 基本概念
进程:是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程一般由程序、数据集合和进程控制块三部分组成。(程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时所需要的数据和工作区;程序控制块包含进程的描述信息和控制信息是进程存在的唯一标志。)
进程具有的特征:
- 动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的;
- 并发性:任何进程都可以同其他进行一起并发执行;
- 独立性:进程是系统进行资源分配和调度的一个独立单位;
- 结构性:进程由程序,数据和进程控制块三部分组成
线程:线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID,当前指令指针PC,寄存器和堆栈组成。而进程由内存空间(代码,数据,进程空间,打开的文件)和一个或多个线程组成。
- 进程和线程的关系
一个操作系统运行着很多个程序也就有很多个进程,而其中一个进程中可能包含着多个线程(大部分程序都是多线程程序)。当线程数为1的时候,进程和线程其实没有什么很大的区别,只是概念上的区别。此外,进程:是操作系统对CPU的抽象,是操作系统分配资源的基本单位 。线程:是操作系统在进程基础上的又一次抽象,是操作系统调度的基本单位。

进程和线程之间的关系图
为什么要采用多线程?
- 线程是并行实体,共享同一个地址空间和全部数据的能力,这是多进程模型没有的。
- 线程比进程更轻量级,比进程更easy(更快)创建和撤销,在有大量线程须要修改和高速修改时,这一特性是十分重要的。
- 若多个线程都是CPU密集型的。多线程那么并不能获得性能上的增强。可是假设存在着大量的计算和大量的I/O处理,拥有多个线程同意这些活动彼此重叠进行从而会加快应用程序运行的速度;
- 多线程系统使得真正的并行有了实现的可能,提高了CPU利用率(充分利用了CPU的性能)。
小结:进程是程序运行资源分配的最小单位 ;线程是 CPU 调度的最小单位,必须依赖于进程而存在 ;线程无处不在
- 上下文切换
CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。
(即使是单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程是同时执行的,时间片一般是几十毫秒(ms))。
- 并行和并发的区别
并发:指应用能够交替执行不同的任务,比如单 CPU 核心下执行多线程并非是同时执行多个任务。
并行:指应用能够同时执行不同的任务
总结:并发是交替执行,并行是同时执行。
并发编程需要注意的问题?
- 安全性问题
- 活跃性问题(饥饿,死锁)
- 性能问题(无限创建线程导致服务器资源耗尽从而宕机)
- Java中创建线程的四种方法
继承Thread类。
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(getName()+":正在执行!"+i);
}
}
}
实现Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i=0;i<20;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("=====");
return "results";
}
}
FutureTask<String> ft = new FutureTask<>(new MyCallable());
new Thread(ft).start();
public class LambdaThread {
public static void main(String[] args) {
new Thread(() -> System.out.println("Lambda表达式任务执行!"))
.start(); // 启动线程
}
}
- Thread和Runnable的区别
- 适合多个相同的程序代码的线程去共享同一个资源。
- 可以避免java中的单继承的局限性。
- 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
- 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。
- 对线程的一些理解
- 结束线程的三种方法
使用 interrupt 方法: 线程内部有个中断标志,当调用线程的 interrupt() 实例方法之 后,线程的中断标志会被置为 true ,可以通过线程的实例方法 isInterrupted() 获取线程的中断标志。
- sleep()方法和yield() 方法
- join()方法
- 线程的运行周期

被折叠的 条评论
为什么被折叠?



