多线程初始总结
什么是程序:
程序(program)是为实现特定目标或解决特定问题而用计算机语言编写的命令序列的集合。为实现预期目的而进行操作的一系列语句和指令。一般分为系统程序和应用程序两大类。
每一个程序在内存中都是以文件的形式存储的。
什么是进程
对应用程序来说,进程就像一个大容器。在应用程序被运行后,就相当于将应用程序装进容器里了,你可以往容器里加其他东西(如:应用程序在运行时所需的变量数据、需要引用的DLL文件等),当应用程序被运行两次时,容器里的东西并不会被倒掉,系统会找一个新的进程容器来容纳它。
进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,它是操作系统动态执行的基本单元。
进程的概念主要有两点:第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。
进程的特征
动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
并发性:任何进程都可以同其他进程一起并发执行
独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;
异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进
结构特征:进程由程序、数据和进程控制块三部分组成。
多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果;但是执行过程中,程序不能发生改变。
什么是线程
线程,有时被称为轻量级进程,是程序执行流的最小单元
线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。
每一个程序都至少有一个线程,那就是程序本身。
线程是程序中一个单一的顺序控制流程。在单个程序中同时运行多个线程完成不同的工作,称为多线程。 引入线程的好处 1 创建一个新线程花费的时间少。 2 两个线程的切换时间少。 3 由于同一个进程内的线程共享内存和文件,所以线程之间互相通信必须调用内核。 4 线程能独立执行,能充分利用和发挥处理机与外围设备并行工作的能力
关于程序并发执行
在大多数计算问题中,仅要求操作在时间上是部分有序的。有些操作必须在其他操作之后执行,另外有些操作却可以并行地执行。
无论是操作系统自身的程序还是用户程序,通常总是存在一些相对独立、但又能并发执行的程序段。
为了合理利用系统资源,更好地发挥各种资源的效益,使各种物理设备之间的时间性限制条件减少到最低限度,最大限度地提高系统的效率,因而引出了多道程序方法。其实质是减少程序的顺序性,提高系统的并行性。
线程调度与优先级
有线程进入了就绪状态,需要有线程调度程序来决定何时执行,根据优先级来调度。
主线程 当一个程序启动时,就有一个进程被操作系统(OS)创建,与此同时一个线程也立刻运行,该线程通常叫做程序的主线程(Main Thread),因为它是程序开始时就执行的,如果你需要再创建线程,那么创建的线程就是这个主线程的子线程。每个进程至少都有一个主线程。 主线程的重要性体现在两方面: 1.是产生其他子线程的线程; 2.通常它必须最后完成执行比如执行各种关闭动作。 线程的定义方法 1.继承Thread类,重写run方法; 2.实现Runnable接口,具体化run方法。 代码示例: 主函数类:
package cn.July.day31.多线程;
import java.io.File;
/***
* 统计某个磁盘文件数量的线程类
*/
public class CountFileTread extends Thread {
/***
* 构造器,传入一个根目录名
*/
public CountFileTread(String rootDirName) {
this.rootDirName = rootDirName;
}
// 线程执行入口:调用线程对象的start()方法后,线程就从它的run方法开始独立执行
public void run() {
long start = System.currentTimeMillis();
int fileCount = countDir(this.rootDirName);
long timeCount = System.currentTimeMillis() - start;
System.out.println("-----驱动器:" + this.rootDirName + "统计完毕:"
+ " ;共有文件数量:" + fileCount + " ;用时(单位:秒):" + timeCount/1000);
}
/***
* 计算一个目录下面所有文件的长度
* @param rootDirName2:要计算的目录名
*@return 文件的总长度
*/
private int countDir(String rootDirName2) {
int count = 0;
//新建文件类对象
File dirFile = new File(rootDirName2);
//如果文件不存在直接返回
if(!dirFile.exists()){
return count;
}
//获得根目录
File[] subFile = dirFile.listFiles();
if(subFile == null){
return count;
}
for(int i = 0;i<subFile.length;i++){
if(subFile[i].isDirectory()){
//如果文件类型是目录,则递归本方法
count+=countDir(subFile[i].getAbsolutePath());
}
else if(subFile[i].isFile()){
//如果文件类型是一般文件的话,计数加一
count++;
}
}
return count;
}
private String rootDirName;
}
package cn.July.day31.多线程;
import java.io.File;
public class MainCount {
/**
* @param args
*/
public static void main(String[] args) {
//取得磁盘目录数组
File[] rootFile = File.listRoots();
//根据根目录个数启动线程
for(int i = 0;i<rootFile.length;i++){
//创建类对象
CountFileTread countFile = new CountFileTread(rootFile[i].getAbsolutePath());
//调用start方法,run开始执行
countFile.start();
}
System.out.println(rootFile.length+"个统计线程对象已启动!");
}
}