线程和进程的区别
进程和线程是操作系统中的两个基本概念。
进程是程序执行的基本单位,每个进程都有自己独立的内存空间和系统资源,它拥有自己的虚拟地址空间、代码段、数据段、堆栈段等。一个程序可以对应多个进程,每个进程之间是独立运行的,互相之间不会影响。
线程是在进程内部执行的一个单一顺序流,它是比进程更小的执行单位。一个进程可以创建多个线程,在同一时间内运行多个线程可以提高执行效率。线程共享所属进程的代码段、数据段和系统资源,但每个线程却有自己独立的运行栈和栈指针寄存器。
所以说,线程必须依赖于进程而存在,并且不能脱离进程而独立存在。在这种关系下,一个进程可以包含多个线程,这些线程共享同一份内存资源,并协同完成任务。同时多个线程之间也需要进行协作与同步,以避免不必要的竞争和冲突。
总而言之,一个进程可以包含多个共享同一资源的并发执行路径即线程。通过合理地利用多线技术可以有效地提高程序性能和响应速度。
终止线程
应该怎么终止一个线程呢?
1.当线程完成任务时。
2.通过使用变量来控制run方法退出的方式停止线程,即通知方式。
这里详细介绍一下2的方式。
在A线程依靠变量循环跑的过程ing,主线程通过修改A线程的变量,来控制线程终止。
为A线程中的变量设置set方法,来修改掉循环条件,从而让run方法走向结束。
所以在A线程想要B线程退出怎么办呢?
在A线程中通知B线程,控制B线程的变量,通知它退出即可。
线程常用方法
设置名称
get,setName
设置优先级
get,setPriority
中断线程
interrupt(不会真正结束线程,所以一般用于中断正在休眠线程)
调用线程
start,run
线程礼让
yield静态方法(让出CPU,让其他线程执行,不一定礼让成功)
线程插队
join(一旦A线程插队成功,则先执行完A线程所有,再继续执行B线程剩下的,相当于阻塞B线程)
线程守护
1.用户线程(工作线程):普通线程
2.守护线程:所有用户线程结束,守护线程自动退出(GC机制)
怎么把一个普通线程变成守护线程?
线程名称.setDaemon(true);
先设置完守护线程,再start方法启动。
线程的7个状态
(此图源于韩顺平老师B站课程)
线程同步机制
在多线程编程中,有一些敏感数据不应该被多个线程同时访问,此时应该使用同步访问技术,保证数据在任何时刻,最多只能有一个线程访问,保证数据的完整性。
同步具体方法:Synchronized(也可以称之为互斥锁)
非静态同步方法的锁对象默认是this,也可以是其他对象(要求是同个对象)。
静态同步方法的锁对象默认为当前类.class。
步骤
1.分析需要上锁代码
2.选择同步代码块或同步方法(尽量为同步代码块,范围小,效率高)
3.要求多个线程锁的对象为同一个即可!
线程死锁
线程之间都占用了对象的锁资源,需要互相返回值才肯相让,才导致了死锁。
举个栗子:
两个人打架。
小明:你先松开手,我再松开
我:你先松开手,我才松开
(此图源于韩顺平老师B站课程)
释放锁
以下操作会释放锁:
当前线程的同步方法,同步代码块执行完毕
当前线程的同步方法,同步代码块遇到break,return
当前线程的同步方法,同步代码块出现异常
当前线程的同步方法,同步代码块执行线程对象的wait方法,当前线程暂停,并释放锁
以下操作不会释放锁:
调用Thread.sleep方法,Thread.yield方法暂停当前线程的执行(休眠多久,外面的线程就会等多久)
其他线程调用了该线程的suspend方法将该线程挂起(suspend和resume方法已被废弃)