第22章多线程1h49’
## 程序 进程 线程
程序:静态的(如一个qq程序)
进程:进行的程序,OS分配资源单位。
(开启3个对话窗口,即3个独立进程,因此数据不共享。)
tasklist PID进程名, taskkill /IM程序名 /PID /F强制(linux中为kill)
线程:是进程中的执行单位(子任务)
(一个进程内的线程资源/数据共享。)
任务管理器,勾选出线程
## 注意点
效率高(线程之间轮换执行,切换的延迟足够短,给人感觉在同步执行。)
存取存在冲突,任何一个线程在什么时候执行时不可预期的,由OS调度。
程序中最重要的资源
1.内存进程统一管理
2.cpu线程(多个)管理
3.IO (没有讲解)
实现多线程的两种方式:
1. 写一个类去继承Thread类,并重写run方法,demo
2. 实现Runnable接口,实现run方法,demo
(因Java无多继承,若有个类已经继承了其他类,就无法继承Thread类实现多线程)
Runnable特点:
Runnable接口只有一个run方法,没有start方法。
Runnable接口和Thread类的对比/关系/优缺点:
1. 关系:
Thread实现了Runnable接口,Thread类是Runnable接口的子类
2. Runnable接口实现多线程的优点
Runnable接口可实现多继承。Thread类实现多线程的话,无法多继承。
Runnable接口可以使多个线程共享相同的资源(书P567的demo)
Thread类的一个对象无论调用多少次start方法,结果都只有一个线程在运行。
(通过Thread.currentThread().getName()获取当前运行的线程名字)
run方法和start方法的区别:
调用start方法方可启动多线程,
而run方法只是Thread类的一个普通方法调用,就是线程要执行的任务,还是在主线程里执行,run执行完则该线程结束。
线程的生命周期:
5个状态:创建, 就绪,运行,-阻塞,终止
关于sleep()和wait()的区别:
wait()会通知当前线程进入睡眠状态
A.sleep是线程类(Thread)的方法,wait是Object类的方法;
B.sleep暂停线程、但监控状态仍然保持,结束后会自动恢复;
C. sleep不释放对象锁,wait放弃对象锁;
常用的线程操作方法:
getname ,getPeriod,isAlive,
setName,setPeriod,setDaemon,
start,sleep,join 的demo,interrupted 的demo,
当线程调用start( )后,其所处状态为(就绪态,非运行态)
中断异常类InterruptedException
Thread.sleep() Object.wait()都可以抛出这类中断异常。
synchronized关键字:
多线程卖票问题,导致有些票被重复卖出,此时的票=临界资源,此时用synchronized关键字修饰,锁定对象,防止其他代码/线程同时访问和使用。(P582)
A.synchronized 修饰代码块,此时需要提供同步对象,该对象的作用范围决定了同步有效范围(即锁定对象)
C.synchronized修饰实例方法,同步范围为当前类的某个实例(即锁定对象)
D.synchronized修饰静态方法,同步范围为所有使用这个类的调用(即锁定类对象)
参考:https://blog.csdn.net/imzoer/article/details/8054151?utm_source=blogxgwz3
进程的同步和互斥
互斥:
某一资源同时只允许一个访问者对其进行访问。
具有唯一性和排他性
无法限制访问者对资源的访问顺序,即访问是无序的。
同步:
基于互斥,经其他机制,实现对互斥资源的有序访问
大多数情况下,同步已经实现了互斥,写入资源是互斥的。
少数情况下,可以允许多个访问者同时访问资源。
死锁:
两个线程都不释放资源,都在等对方的资源
ReentrantLock();//可重入锁
线程池:
进程的调度算法(很少被问到)
虚寸,实存,共享内存
虚寸,进程需要的虚拟内存大小
实存,代码和数据需要的内存
共享内存,自身+其他进程的共享内存。