一文搞懂线程和进程

前置知识

区分线程和进程

什么是进程?

是操作系统进行资源分配和调度的基本单位。

什么是进程状态?

一个进程的生命周期可以划分为一组状态,进程状态标志了进程处于生命周期的哪个阶段。它反应了程序的执行过程。

下图黄色文字代表操作系统中进程状态,即

waiting
new
ready
running
terminated

活的进程(抛开线程的出生和死亡)至少有3种状态:

  • 就绪态:具备了运行条件,等待CPU分配处理资源
  • 运行态:CPU正在执行
  • 等待态:又叫阻塞态,指进程正在等待某件事情的完成,不能够运行。

另外两种状态:

  • 新建态:对应进程刚刚被创建的状态。创建进程有两个步骤:第一步:为新进程创建进程管理块;第二步:让该进程进入就绪态。
  • 终止态:不再执行的进程,但是依然保留在操作系统中等待着善后。一旦其他进程完成了对终止态的进程的信息的抽取之后,操作系统将删除该进程。

可能存在的状态转换:

  1. null----->新建态:执行程序,创建一个子进程。
  2. 新建态----->就绪态:在当前系统性能和内存容量允许的情况下,操作系统完成了进程创建的必要操作。
  3. 终止态----->null:完成善后操作,释放内存。
  4. 运行态---->终止态:进程到打程序节点,寿终正寝。或者出现了无法克服的错误,或者被操作系统所终结(强制关机),或者被父进程所终结。
  5. 就绪态—>终止态:父进程终结子进程
  6. 等待态—>终止态:父进程终结子进程

在这里插入图片描述

进程可能的状态转换有哪些?

  1. 就绪态----->运行态:CPU空闲时,从就绪状态的进程中选一个来执行。这里相当于是在等CPU来执行我这个进程。
  2. 运行态----->就绪态:CPU分给每个进程的时间片是有限的,该进程的运行时间一用完,CPU就跑去执行其他进程去了。或者在执行过程中,碰到了一个拥有更高优先权的进程,也会让CPU放弃当前执行的线程,转而去执行优先级更高的进程。此时,则当前进程从运行态转换成了就绪态。
  3. 运行态---->等待态:正在执行的进程发生了某个等待事件而无法执行,比如:发生了I/O请求(等待外设传输)

CPU的时间很宝贵,不会一直在这里等你。

  1. 等待态----->就绪态:进程所等待的事件已经结束,这时进程进入到就绪队列中。

状态转化图(三态模型)
在这里插入图片描述

2种不可能存在的转换

  1. 等待态----> 运行态:这之间隔了一个就绪态。CPU只会从就绪状态的队列中选择进程来执行。
  2. 就绪态----> 等待态:这之间隔了运行态,进程没有执行,不可能会到等待态。

黑色文字代表线程状态,即

  1. 新建,new
  2. 可运行,runnable
  3. 计时等待
  4. 无限等待
  5. 锁阻塞
  6. 终止,terminated

在这里插入图片描述

什么是线程?

是进程内部的一个独立的执行单元。一个进程可以并发的运行多个线程。可以将进程看做是一个单CPU操作系统,而线程就是这个系统中运行的多个任务。

注意事项

在这里插入图片描述

亮点

  • JVM采用的是抢占式调度,有点类似于非公平锁的机制。这造成了线程分配的随机性。
  • JVM负责线程的调度

在这里插入图片描述

线程有哪几种状态?

在这里插入图片描述

  • NEW,刚刚创建,尚未启动
  • RUNNABLE,可运行
  • BLOCKED,锁被其他线程占有。
  • WAITING,无限期等待另一个线程执行结束,等着别人叫醒它。(notify)
  • TIMED_WAITING,计时等待。
  • TERMINATED,已经退出的线程

线程之间的转换是怎样的?

在这里插入图片描述

创建线程的几种方式

方式一:继承thread类

第一步:自定义一个线程类,重写run方法

package cn.lizemin.demo.thread;

/**
 * @author: lizemin
 * @version: 1.0
 */
public class MyThread extends Thread{
    public MyThread(String name){
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
        	//打印当前线程的名字
            System.out.println(getName()+" "+i);
        }
    }
}

第二步:启动多线程,ThreadDemo
在这里插入图片描述

package cn.lizemin.demo.thread;

/**
 * @author: lizemin
 * @version: 1.0
 * 使用方法一:
 * 1.自定义一个类继承thread类
 * 2.run方法中放新的线程要执行的代码
 */
public class ThreadDemo{
    //这是一个main方法,是程序的入口
    public static void main(String[] args) {
        System.out.println("main线程已开启");
        //创建线程对象
        MyThread myThread = new MyThread("小强");
        //开启新的线程
        myThread.start();
        for (int i = 0; i < 20; i++) {
            System.out.println("旺财:"+i);
        }
        
    }
}

第三步:执行代码
可以看到两个线程交替执行,旺财和小强交替出现。

方式二:定义自定义类实现runnable接口

1.自定义实现runnable接口,MyRunnable,并实现run方法。

package cn.lizemin.demo.thread;

/**
 * @author: lizemin
 * @version: 1.0
 */
public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
        //打印当前线程的名字
            System.out.println(Thread.currentThread().getName()+" "+i);

        }

    }
}

2.创建自定义类对象,在创建thread对象时,将其作为thread对象的参数传递。

package cn.lizemin.demo.thread;

/**
 * @author: lizemin
 * @version: 1.0
 * 2.run方法中放新的线程要执行的代码
 */
public class ThreadDemo{
    //这是一个main方法,是程序的入口
    public static void main(String[] args) {
        System.out.println("main线程已开启");
        MyRunnable myRunnable = new MyRunnable();
        //创建线程对象
        Thread thread = new Thread(myRunnable,"小强");
        Thread thread2 = new Thread(myRunnable,"旺财");
        //开启线程
        thread.start();
        thread2.start();

    }
}

查看线程的状态

package cn.lizemin.demo.thread;

/**
 * @author: lizemin
 * @version: 1.0
 * 使用方法一:
 * 1.自定义一个类继承thread类
 * 2.run方法中放新的线程要执行的代码
 */
public class ThreadDemo{
    //这是一个main方法,是程序的入口
    public static void main(String[] args) throws InterruptedException {
        System.out.println("main线程已开启");
        MyRunnable myRunnable = new MyRunnable();
        //创建线程对象
        Thread thread = new Thread(myRunnable,"小强");
        Thread thread2 = new Thread(myRunnable,"旺财");
        //创建线程对象后,查看线程状态:new
        System.out.println("thread当前的线程状态为:"+thread2.getState());
        //开启线程
        thread.start();
        thread2.start();
        //开启线程后,查看线程状态:runnable
        System.out.println("thread当前的线程状态为:"+thread2.getState());
        Thread.sleep(500);
        //线程沉睡后,查看线程状态:TERMINATED
        System.out.println("thread当前的线程状态为:"+thread2.getState());


    }
}

流程图
当线程结束后,会进入到终止状态
在这里插入图片描述

参考资料

探究Java线程状态及转换

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值