一、线程的生命周期
线程的生命周期分为五个状态
1. 新建
2. 就绪
3. 运行
4. 死亡
5. 阻塞
每个状态相应的执行方法请看下图:
二、程序、进程、线程的概念
- 程序:为完成特定任务、用某种语言编写的一组指令的集合。指一段静态的代码,静态对象。
- 进程:是程序的一次执行过程,或者是正在运行的一个程序,如运行中的播放器。程序是静态的,进程是动态的,它有自己的生命周期
- 线程:进程可以细化为线程,是程序内部的一条执行路径。(一个程序可以同一时间执行多个线程 )
三、使用多线程的优点
- 提高应用程序的响应
- 提高计算机系统的cup的利用率
- 改善程序结构
四、线程的实现方式
线程的常见时间方式有两种。
- 继承Thread类,重写run方法
- 实现Runable接口,重写run方法
五、线程的常用方法
线程的常用方法基本都在Thread中调用
- 获得线程名称
getName(); - 获取当前线程对象
currentThread(); - 判断当前线程是否启动
isAlive(); - 线程的强行运行
join(); - 线程的休眠
sleep(); - 线程的礼让
yield();
六、线程的优先级
默认是5,不绝对是MAX线程先执行。
优先级的顺序设置
- MIN_PRIOPRITY
- MAX_PRIORITY
- NORM_PRIORITY
七、线程同步
同步就是让线程共享资源
同步代码块
在代码上加上 ‘synchronized’ 关键字
同步代码块格式:
synchronized(同步对象){
同步代码块;
}
- 同步方法
synchronized public void 方法名称(){
}
八、死锁
线程之间相互争夺资源互相不肯释放的情况。
解决办法之一:线程的礼让 yield() (让别的线程执行完在执行本线程)
public class DeadLock {
static StringBuffer sb1 = new StringBuffer();
static StringBuffer sb2 = new StringBuffer();
public static void main(String[] args) {
//线程1
new Thread() {
long start = System.currentTimeMillis();
public void run() {
synchronized (sb1) {
sb1.append("A");
try {
Thread.currentThread().sleep(10); //让该线程休眠10秒
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (sb2) {
sb2.append("B");
System.out.println(sb1);
System.out.println(sb2);
}
}
}
}.start();
//线程2
new Thread() {
public void run() {
synchronized (sb2) {
sb1.append("C");
synchronized (sb1) {
sb2.append("D");
System.out.println(sb1);
System.out.println(sb2);
}
}
}
}.start();
}
}
Thread1-->sb1 //线程一持有sb1对象锁
sleep(10); //休眠的过程中可能被其他线程占据了资源
Thread1-->sb2 //线程一持有sb2对象所失败(因为被其他线程占据了资源,不能够往下执行)
Thread2-->sb2 //线程二持有sb2对象锁
Thread2-->sb1 //线程二持有sb1对象锁失败,原因是该对象锁被线程一持有二没有释放资源。
通过上面的步骤产生了死锁的现象,即不同的对象分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源。
死锁的必要条件
- 互斥条件:一个资源每次只能被一个进程使用;
- 请求与保持条件:一个进程因请求资源阻塞时,对已获得的资源不释放;
- 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺;
- 循环等待条件:若干进程之间形成一种头尾相接循环等待资源关系。
死锁的预防
- 可剥夺资源(破坏不剥夺条件)
- 资源一次性分配(破坏请求与保持条件):新进程未满足条件时,释放资源
- 资源有序分配法(破坏循环等待条件)
死锁的避免
银行家算法
- 死锁的检测
给每个进程和资源分配唯一编号,然后建立资源分配表和进程等待表
死锁的解除
- 剥夺资源:从其他进程剥夺资源给死锁进程、以解除死锁状态
- 撤销进程:可以直接撤消死锁进程或撤消代价最小的进程,直至有足够的资源可用,死锁状态.消除为止;所谓代价是指优先级、运行代价、进程的重要性和价值等。
九、线程池
- 概念
线程池实现了一个java高并发、多线程的、可管理统一调度器,减少线程的创建和销毁对象的次数。
线程池的优点
- 降低资源的消耗:降低创建线程和销毁线程的消耗。
- 提高响应速度:当任务达到时,任务不需要创建线程就可以执行。
- 提高线程的可管理性:避免无线创建线程、统一对线程进行调度。