• 进程和线程


    1.进程和线程

      进程:是一个正在执行中的程序。
                每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。
      线程:就是进程中的一个独立的控制单元,是比进程更小的执行单位。线程只是一种为单一处理器分配执行时间的手段
         线程在控制着进程的执行。

      一个进程中至少有一个线程。

      线程的四个状态:运行,就绪,挂起,结束。

      线程的作用:就是用来执行代码的。

    2.什么是多线程?

      多线程是指一个进程在执行过程中可以产生多个线程,这些线程可以同时存在,同时运行,一个进程可能包含了多个同时执行的线程。如,迅雷下载,可以下载多个任务,就是多线程

    3.创建多线程的第一种方式:继承Thread类。
      (1)定义类继承Thread类
      (2)覆写Thread 类中的run()方法
        目的:将自定义代码存储在run方法,让线程运行
      (3)调用线程的start方法。该方法有两个作用:启动线程,调用run方法。所以启动一个线程要用start()方法
    package org.lxh.demo9.threaddemo;
    class MyThread extends Thread 
    {
        private String name;
        public MyThread(String name)  //通过构造方法设置属性内容
        {
        this.name =name;
        }
        public void run(){    //覆写Thread类中的run()方法
            for (int i=0;i<10;i++)
            {
                System.out.println(name+"运行,i="+i);
            }
        }
    
    }
    public class ThreadDemo2 {
        public static void main(String[] args) {
            MyThread mt1= new MyThread("线程A");    //创建好了一个线程
            MyThread mt2= new MyThread("线程B");
            mt1.start();   //启动多线程,并执行该线程的run方法,若用mt1.run();仅仅是对象调用方法,而线程创建了,并没有运行。等到把run方法执行完了,再执行下一个。
            mt2.start();  //启动多线程
        }
    }
    
      发现运行结果,每次都不同,因为多个线程都在获取CPU的执行权,CPU执行到谁,谁就运行。
      明确一点,在某一个时刻,只能有一个程序在运行。(多核除外)CPU在做着快速的切换,已达到看上去是同时运行的结果。
      我们可以形象把多线程的运行行为看成在互相抢夺CPU的执行权
      这就是多线程的一个特性:随机性。谁抢到谁执行。至于执行多长,CPU说的算。

       java程序每次运行至少启动几个线程? 

       至少会启动2个线程,一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类时,实际上都会启动一个JVM,每一个JVM实际上就是在操作系统中启动了一个进程,java本身具备了垃圾的收集机制。

       在主函数main中执行的线程就是主线程

    例题1:关于进程和线程描述正确的是()ABD
      A.线程不拥有系统资源,但可以访问隶属于进程的资源
      B.在创建或销毁进程时,系统开销明显大于创建或销毁线程时开销
      C.进程是调度和拥有资源的基本单位(错误)
      D.不仅进程可以并发执行,同一个进程的多个线程之间也可以并发执行

       解释:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位

        (1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;
        (2)资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源
        (3)线程是处理器(CPU)调度的基本单位,但进程不是.
        (4)二者均可并发执行.

     例题2:从资源管理的角度看,进程调度属于()。

        处理器(CPU)管理

     例题3:同一个进程的多个线程堆栈共享状况哪个描述正确?A

        A.堆共享,栈私有

        B.堆私有,栈共享

        C.堆共享,栈共享

        D.堆私有,栈私有

    解释:

      线程占有的都是不共享的,其中包括:栈、寄存器、状态、程序计数器

      线程间共享的有:堆,全局变量,静态变量;

      进程占有的资源有:地址空间,全局变量,打开的文件,子进程,信号量、账户信息。

     例题4:对进程和线程的描述,以下正确的是()D
        A.父进程里的所有线程共享相同的地址空间,父进程的所有子进程共享相同的地址空间
        B.改变进程里面主线程的状态会影响到其他线程的行为,改变父进程的状态不会影响到其他子进程
        C.多线程会引起死锁,而多进程不会
        D.以上选项都不正确

     解释: 

      父进程和子进程都有自己独立的地址空间
      父进程结束,所有子进程都结束,进程结束,所有线程都结束;
      如果多个进程同时占有对方需要的资源而同时请求对方的资源,而它们在得到请求之前不会释放所占有的资源,那么就会导致死锁的发生,也就是进程不能实现同步。
      多线程和多进程都会引起死锁,一般说的死锁指的是进程间的死锁。
     
     例题5:同一进程下的线程可以共享以下?(BD)

    A. stack           B.data section        C.register set     D.file fd

        线程共享的环境包括:进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。 进程拥有这许多共性的同时,还拥有自己的个性。有了这些个性,线程才能实现并发性。这些个性包括:
        1.线程ID
          每个线程都有自己的线程ID,这个ID在本进程中是唯一的。进程用此来标
       识线程。
        2.寄存器组的值
           由于线程间是并发运行的,每个线程有自己不同的运行线索,当从一个线
       程切换到另一个线程上时,必须将原有的线程的寄存器集合的状态保存,以便
       将来该线程在被重新切换到时能得以恢复。(PCB)
        3.线程的堆栈
           堆栈是保证线程独立运行所必须的。
           线程函数可以调用函数,而被调用函数中又是可以层层嵌套的,所以线程
       必须拥有自己的函数堆栈,使得函数调用可以正常执行,不受其他线程的影
       响。
        4.错误返回码
           由于同一个进程中有很多个线程在同时运行,可能某个线程进行系统调用
       后设置了errno值,而在该线程还没有处理这个错误,另外一个线程就在此时
       被调度器投入运行,这样错误值就有可能被修改。
           所以,不同的线程应该拥有自己的错误返回码变量。
        5.线程的信号屏蔽码
           由于每个线程所感兴趣的信号不同,所以线程的信号屏蔽码应该由线程自
       己管理。但所有的线程都共享同样的信号处理器。
      6.线程的优先级
           由于线程需要像进程那样能够被调度,那么就必须要有可供调度使用的参
       数,这个参数就是线程的优先级。

     关于PCB(Process Control Block)

      进程控制块是进程实体的一部分,是操作系统中最重要的记录型数据结构。PCB中记录了操作系统所需要的、用于描述进程情况及控制进程运行所需要的全部信息进程控制块的作用,是使一个在多道程序环境下不能独立进行的程序(含数据),成为一个能独立运行的基本单位,一个能与其他进程并发执行的进程。或者说,操作系统是根据PCB来对并发执行的进程进行控制和管理。

    例题6:进程和线程的区别。

      一个程序至少有一个进程,一个进程至少有一个线程

    (1)进程是系统进行资源分配的基本单位有独立的内存地址空间线程CPU调度的基本单位没有单独的地址空间,有独立的栈,寄存器,程序计数器,局部变量等。

    (2)创建进程的开销大,包括创建虚拟地址空间等需要大量的系统资源;创建线程开销小,基本上只有一个内核对象和一个堆栈。

    (3)一个进程无法直接访问另一个进程的资源同一进程内的多个线程共享进程的资源

    (4)进程切换开销大,线程切换开销小;进程间通信开销大,进程间通信开销小。线程属于进程,不能独立运行。每个进程至少有一个线程,成为主线程。

     例题7:下列关于线程调度的叙述中,错误的是()BC

      A.调用线程的sleep()方法,可以使比当前线程优先级低的线程获得运行机会

      B.调用线程的yeild()方法,只会使与当前线程相同优先级的线程获得运行机会

      C.具有相同优先级的多个线程的调度一定是分时的

      D.分时调度模型是让所有线程轮流获得CPU使用权

     解释:

    A选项,sleep()方法强制使当前线程休眠,释放CPU资源(不释放锁,释放CPU执行权),以便使得其他所有线程有机会运行。
    B选项,yield()方法使得当前的线程让出CPU的使用权,以使得比该线程优先级相同或更高的线程有机会运行。该线程在让出CPU使用权之后可能再次被选中,因此yield()方法可能会不起作用(这也说明了yield()方法不会使得比当前线程优先级低的线程运行)。
    C选项,java虚拟机中如果多个线程优先级相同,则会随机选择一个线程占用CPU,处于运行状态的线程会一直运行,直至它不得不放弃CPU为止,因此不一定是分时调度。

    关于进程和线程之间的区别,阮一峰网络日志,有一个很形象的解释。

    http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html

  • 相关阅读:
    Asp.net MVC 视图引擎集合
    技术债务管理计划
    Android应用程序反编译
    Managed Extensibility Framework(MEF) 2 框架新特性介绍
    企业搜索引擎开发之连接器connector(十四)
    企业搜索引擎开发之连接器connector(十)
    企业搜索引擎开发之连接器connector(十一)
    zookeeper 原理
    企业搜索引擎开发之连接器connector(十二)
    jspf插件框架
  • 原文地址:https://www.cnblogs.com/GumpYan/p/5743496.html
Copyright © 2020-2023  润新知