1. 什么是进程
进程是由程序、数据及系统资源组成的一次程序运行活动的实体.
进程包含:数据、线程、进程控制块(PCB)、程序;一个程序的多个运行实例对应多个进程,每个进程包含一个或多个线程。
按照功能可分为:交互进程和后台进程;
按照归属分为:用户进程和系统进程。
进程控制块(PCB): 操作系统定义的、用于记录进程状态及控制进程运行所需信息的数据结构。
2.什么是线程
**进程中系统进行调度的最小执行单元,包括:用户线程和守护线程**
用户线程是为完成具体业务功能而创建,任务完成或异常结束而终止的线程;为其它线程提供服务、随着服务的用户线程终止而终止的线程。
一个进程中至少有一个线程,这个线程就是主线程,可以说main()方法就是主线程的入口;
3.如何使用线程
1、定义线程执行体(线程中实现具体功能的方法体)
1):继承Thread类,重写run()方法;
2):实现Runable接口,作为线程的target;
2、创建线程对象
1):创建线程的子类对象
2):创建Runnable接口实现类对象
3、启动线程
调用start( )方法启动线程;
4、线程运行
5、线程终止
4 两种创建线程方式的比较
1、继承Thread类
优点:编写简单,可直接操作线程
缺点:不能再继承其它类
2、实现Runnable接口
优点:可以继承其它类,便于共享资源
缺点:需要通过Thread.currentThread()方法获取线程对象再进行操作
这两种创建线程的方式归根结底都是在run()方法里实现具体的功能。无论是继承Thread类重写的run()方法还是直接实现Runnable接口,其实都是Runnable接口里声明的run()方法,Thread类的run()方法也是实现的Runnable接口,run()方法是无参无返回值的。所以两种方式创建的线程都是带不回来返回值的。
5.需要获取任务执行结果怎么办?
创建能够获取执行结果的线程:Callable接口和FutureTask泛型类
Callable是个泛型接口,接口中声明了一个call()方法,call()方法是有返回值的,返回值类型由类型参数指定,抛出异常。FutureTask是一个泛型类,它实现了一个叫做RunnableFuture的泛型接口,这个RunnableFuture泛型接口的名字前面这部分熟悉吧?Runnable。就是前面讲过的Runnable,后面是Future,未来、将来的意思,这个RunnableFuture接口继承了Runnable接口和一个叫Future的泛型接口。
**实现过程**
定义一个类实现Callable接口,实现Callable接口的call( )方法
创建Callable接口实现类对象,以Callable实现类对象作为参数构建FutureTask类对象
以 FutureTask实现类对象作为参数构建Thread类对象,调用start()方法启动线程
调用FutureTask实现类对象的get()方法获取执行结果
6.start()和run()的区别和联系
直接调用run()方法不会启动新线程--既然无论哪种方式创建线程,都是调用start()方法启动线程。所以说start()是启动线程的唯一方式。
而run()是定义线程执行体的具体逻辑,他不能是线程启动.
7.线程的生命周期级调度原则
通过一个图来解析线程整个生命周期的各种状态之间的切换和触发状态切换的事件。为了区分线程正在CPU运行和等待被调度运行,通常把等待被调度运行时的状态称为“就绪”状态,把正在运行的状态称为“运行”状态。启动线程后,它并不是立刻被执行,这时称它为就绪状态,获得CPU资源后真正开始运行,称它为运行状态。运行中需要等待信号或休眠会进入WAITING或TIMED_WAITING状态,等待资源或获取锁会进入BLOCKED状态,统称它为阻塞状态。阻塞条件解除或等待时间结束后线程不能马上回到执行状态,而是去等待系统调度获取CPU资源。
8.线程调度原则
>>>>>时间片轮询-按优先级排序-同级先到先服务
线程启动后要等待系统调度才能获取CPU资源,几千个线程都等着执行,系统怎么决定执行哪个线程呢?CPU的时间是分成一个个很短的时间片的,快速的切换执行,让用户感觉每个程序都一直在运行。在分配每个时间片的时候,是按照线程的优先级选择的,同优先级的先到先服务。
注:可以控制线程来改变线程的执行*****************