系列文章目录
暂无
文章目录
一、线程与进程
1.进程
概念
进程是操作系统环境中的基本成分、是系统资源分配的基本单位。从用户角度来看,进程是应用程序的一个执行过程。
特点
- 进程是线程的容器
- 占用特定的地址空间
- 进程之间相互独立
- 缺点:频繁地切换进程会造成CPU的负担
2.线程
概念
线程是CPU执行的最小片段。可以理解为进程中独立运行的子任务
特点
- CPU的一个运算核心(单核)同一时间只能运行一个线程
- 一个进程包含一个或多个线程。一个线程不能独立的存在,它必须是进程的一部分
- 一个进程中的线程共享相同的内存单元,因此他们可以实现数据的交互、同步操作
- 线程更轻量级,更容易切换
线程的优先级
每一个 Java 线程都有一个优先级,取值范围为1~10,默认为5。
线程的优先级不能保证线程一定优先执行,只能让它尽可能优先执行
线程的五种状态
新生状态
当创建好线程对象,未start之前,此时线程有线程空间,没有满足运行条件,没有CPU资源
就绪状态
当线程对象调用了start()方法之后,线程进入就绪状态。线程会添加到一个就绪队列中,队列中的所有的线程同时去抢占CPU资源。有运行条件,没有资源
运行状态
当当前进程获取到CPU资源后,就绪对列中的所有线程去抢占CPU资源,谁先抢到谁先执行,在执行的过程中就叫做运行状态,抢占到CPU资源,执行代码逻辑开始。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
运行状态->就绪状态:时间片用完
阻塞状态
在程序运行过程中,发生某些异常情况,导致当前线程无法再顺利执行下去,此时会进入阻塞状态,进入阻塞状态的原因消除后,阻塞队列会再次进入就绪状态中,随机抢占CPU资源,等待执行
进入阻塞状态的原因
- sleep方法
- 等待I/O设备等资源
死亡状态
当运行中的线程正常执行完所有的代码逻辑,或者因为异常情况导致程序结束叫做死亡状态
进入死亡状态的原因
- 正常运行完成且结束
- 人为中断,比如使用stop方法
- 程序抛出未捕获的异常
二、线程的创建
1.继承Thread类本身
流程
- 创建一个继承Thread的子类
public class ThreadDemo extends Thread
- 在子类中重写run方法
- 创建子类对象并调用start()方法
样例
public class ThreadDemo extends Thread{
@Override
public void run(){
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" ----------- "+i);
}
}
public static void main(String[] args) {
ThreadDemo threadDemo=new ThreadDemo();
threadDemo.start();
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" =========== "+i);
}
}
}
运行结果
因为线程谁先抢占到资源不确定,所以每次运行的结果有可能不一样
2.实现Runnable接口
因为继承Thread本质上也是通过实现一个Runnable接口来创建进程,所以我们可以直接在自己创建的类中实现Runnable接口
流程
- 对自己写的类实例Runnable接口
public class RunnableDemo implements Runnable
- 重写run方法
- 创建Thread对象,再将创建好的Runnable子类实例作为thread的构造参数
- thread.start()启动
样例
public class RunnableDemo implements Runnable{
@Override
public void run(){
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" ----------- "+i);
}
}
public static void main(String[] args) {
// ThreadDemo threadDemo=new ThreadDemo();
// threadDemo.start();
RunnableDemo runnableDemo=new RunnableDemo();
Thread thread=new Thread(runnableDemo);
thread.start();
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" =========== "+i);
}
}
}
运行结果
PS:
- 因为Java中的单继承规则,实现Runnable接口的方法只是实现了一个接口,还可以继承其他类。而继承Thread的方法无法再继承其他的类
- 实现Runnable接口的方法因为可以同一个Runnable子类对象创建多个线程,所以彼此之间可以实现数据共享。而继承Thread的方法因为一个子类对象只能创建一个进程,所以数据不会互通
总结
今天开始多线程的学习了,fighting!