java多线程-线程生命周期及状态
目录标题
- 创建线程的四种方式
- 线程的状态和生命周期
- 线程中改变状态的方法
- 线程停止
- 设置和获取线程名
- 线程优先级
创建线程的四种方式
- 继承Thread类
- 实现Runnable接口
- 使用Callable和Future创建线程
- 使用Executor框架创建线程池
创建线程的具体实现可以参考创建线程的四种方式
线程的状态和生命周期
线程的状态我们可以在api文档中搜索Thread.State便可以得到下列的六种状态。
Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种不同状态的其中一个状态,线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换
状态 | 描述 | 官方解释 |
---|---|---|
新建状态(NEW) | 创建线程对象 | 至今尚未启动 |
就绪状态(RUNNABLE) | start()方法 | 正在java虚拟机中执行的线程 |
阻塞状态(BLOCKED) | 无法获得锁对象 | 受阻塞并等待某个监视器锁的线程 |
等待状态(WAITING) | wait()方法 | 无限期的等待另一个线程来执行某一特定操作的线程 |
计时状态(TIMED_WAITING) | sleep()方法 | 等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态。 |
结束状态(TERMINATED) | 全部代码运行完毕 | 已退出的线程处于这种状态。 |
线程的状态图如下,我会不断完整,而上面的一些方法都会一一学习,呢么这些线程是怎么变化的呢?
所以我们就会学习到一些改变状态的方法
线程中改变状态的方法
实例:无限期等待/限期等待/阻塞
线程停止
java中原来提供的一个方法stop,使用stop方法强行终止线程,但是不推荐使用这个方法,因为stop和suspend、resume一样,都是过期作废的方法。
所以我们一般采用通知机制来停止-》其实很容易理解,定义一个布尔值,指定条件判断停止
实例
设置和获取线程名
方法介绍
方法名 说明 void setName(String name) 将此线程的名称更改为等于参数name String getName() 返回此线程的名称 Thread currentThread() 返回对当前正在执行的线程对象的引用 代码演示
package m08.d07.xian;
public class Test1 {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr); // 创建线程
Thread t2 = new Thread(mr, "线程二"); //创建线程并设置线程名为线程二
Thread t3 = new Thread(mr);
t3.setName("线程三");
t1.start();
t2.start();
t3.start();
System.out.println("在main执行的线程的名字是:" + Thread.currentThread().getName());
// 打印如下,因为是线程所有没有顺序
// 在main执行的线程的名字是:main
//当前线程的名字是:线程二
//当前线程的名字是:线程三
//当前线程的名字是:Thread-0
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("当前线程的名字是:" + Thread.currentThread().getName());
}
}
线程优先级
线程可以划分优先级,优先级高的线程得到的CPU资源比较多,也就是CPU优先执行优先级高的线程对象中的任务。
线程调度
两种调度方式
- 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
- 抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些
- Java使用的是抢占式调度模型
随机性
假如计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随机性,因为谁抢到CPU的使用权是不一定的
优先级相关方法
方法名 说明 final int getPriority() 返回此线程的优先级 final void setPriority(int newPriority) 更改此线程的优先级线程默认优先级是5;线程优先级的范围是:1-10 代码演示
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "---" + i);
}
return "线程执行完毕了";
}
}
class Demo {
public static void main(String[] args) {
//优先级: 1 - 10 默认值:5
MyCallable mc = new MyCallable();
MyCallable mc2 = new MyCallable();
FutureTask<String> ft = new FutureTask<>(mc);
FutureTask<String> ft2 = new FutureTask<>(mc2);
Thread t1 = new Thread(ft,"线程1");
Thread t2 = new Thread(ft2,"线程2");
t1.setPriority(10);
System.out.println("t1线程优先级" +t1.getPriority());//5
t1.start();
System.out.println("t2线程优先级"+t2.getPriority());//
t2.start();
}
}
还没有评论,来说两句吧...