【计算机基础】进程和线程

是什么?

  线程,程序执行流的最小执行单位,是行程中的实际运作单位,经常容易和进程这个概念混淆。那么,线程和进程究竟有什么区别呢?首先,进程是一个动态的过程,是一个活动的实体。简单来说,一个应用程序的运行就可以被看做是一个进程,而线程,是运行中的实际的任务执行者。可以说,进程中包含了多个可以同时运行的线程

 

程序计数器(线程私有):一块较小的内存空间,是当前线程所执行的字节码的行号指示器,每个线程有自己独立的程序指示器。

虚拟机栈(线程私有):是描述java方法执行的内存模型,每个方法被执行的同时会创建一个栈帧用于存储局部变量、操作数栈、动态链接、方法出口等信息。每个方法从调用到执行完成的过程,就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。

本地方法区(线程私有):本地方法栈和虚拟机栈类似,不同的是本地方法栈为Native方法(用Native修饰的方法)服务。

 

线程的生命周期(5种状态):新建(New)、就绪runnable、运行running、阻塞blocked、死亡dead,当线程启动时,也不能一直霸占cpu独自使用,cpu需要在多线程之间切换, 所以线程状态会在运行和阻塞之间切换。

  •   线程新建时,jvm为线程分配内存并初始化其成员变量的值。
  •   就绪状态,当线程对象调用start()方法后,线程进入就绪状态,java虚拟机会为期创建方法调用栈和程序计数器,等待调度使用
  •   运行状态,如果处于就绪状态的线程获得了cpu,就执行run()方法的线程执行体。
  •   阻塞状态,线程由于某种原因放弃cpu使用权,即让出了cpu timeslice,暂时停止运行,直到再次获得cpu使用权,变为runnable状态,才有机会获得cpu timeslice转到running状态。阻塞情况分3种:等待阻塞(running的线程执行o.wait()方法,JVM会将其放入等待队列中)、同步阻塞(runnable的线程在获取对象的同步锁时, 同步锁已有其他线程占用,则JVM将线程放到锁池中)其他阻塞(running的线程执行threads.sleep()或t.join()方法或发出IO请求,JVM把线程置为阻塞。当sleep超时或join等待线程终止或超时、IO处理完毕,会进入runable状态)
  •   线程死亡:线程结束就是死亡状态,有三种方式:正常结束(run(),或call()方法执行完,线程正常结束)异常结束(线程抛出一个Exception或Error)调用stop()(调用线程的stop()方法结束线程,该方法通常容易造成死锁,不推荐使用)

 线程的基本方法?

  wait   notify    notifyAll    sleep    join    yield等

调用wait方法,线程进入Waiting状态,只有等待另外线程的通知或被中断才会返回,等待状态的线程会释放对象锁,因此,wait方法一般用在同步方法或同步代码块中。

sleep,线程休眠,调用该方法线程进入WATING状态,且线程不释放对象锁。

yied,会让线程让出CPU时间片,与其他线程重新竞争CPU时间片

interrupt,中断一个线程,是给线程一个通知信号,会影响线程内部的中断标识位,这个线程并不会因此改变状态。

 

 

 

 

举例:QQ运行,为一个进程,在QQ中执行多种操作为不同线程。

 

线程池是什么?

  一种线程的使用模式,线程池维护多个线程,等待着管理者分配并发可执行的任务,避免了在处理短时间任务时创建和销毁线程的代价。

  组成:

    线程池管理器:用于创建并管理线程池

    任务队列:用于存放待处理的任务,提供一种缓冲机制

    工作线程:线程池中的线程

    任务接口:每个任务必须实现的接口,用于工作线程调度的运行

线程池的原理?

  线程池主要的作用是控制运行的线程数量,处理过程中将任务放入到队列,然后在线程创建后启动这些任务,如果线程数量超出了最大数量,超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务执行。他的主要特点为:线程复用、管理线程、控制最大并发数。

  线程复用:threads类有一个start()方法,当调用start启动线程后JAVA虚拟机会调用run方法,run方法中调用了runnable对象的run方法,我们可以继承重写thread类,在start方法中添加不断循环调用传递来的Runnable对象,循环方法中不断调用runnable方法使用 队列 实现的。

线程池工作原理?

   1.线程池刚创建时,里面没有线程,任务队列是作为参数传进来的。不过就算任务队列中有任务,线程池也不会马上执行它们。

  2.当调用execute()方法添加一个任务时,线程池会做如下判断:

    正在运行的线程数量  小于corePoolSize,那么马上创建线程运行任务

    正在运行的线程数量  >= corePoolSize,那么任务会放到队列

    如果队列满了,正在运行的线程数量小于maximumPoolSize,会立即创建非核心线程运行此任务

    如果队列满了, 正在运行的线程数量大于 等于maximumPoolSize,线程池会抛出RejectExecutionException

  3.当一个线程完成任务时,它会从队列中取出一个任务来执行

  4.当一个线程无事可做,超过一定时间(keepAliceTime)时,线程池会判断,如果当前运行的线程数大于corepoolSize,那么这个线程会被停掉。当线程池中所有任务完成,它最终会收缩到corePoolSize的大小

 

Linux:

jps,java进程pid的命令

jstack,jstack –l 23561(进程号),查看进程下的线程

 

posted @ 2020-07-19 15:57  月月professor  阅读(31)  评论(0)    收藏  举报