1.进程与线程的区别

进程

进程是系统进行资源分配和调度的一个独立单位。进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。

每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。

线程

线程是程序中一个单一的顺序控制流程.在单个程序中同时运行多个线程完成不同的工作,称为多线程.

线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。

比如Java.exe进程中可以运行很多线程。线程总是属于某个进程,进程中的多个线程共享进程的内存。“同时”执行是人的感觉,在线程之间实际上轮换执行。



2.使用多线程的优点

1.与用户的更好交互 。

即使只有一个处理器,Java中的线程好像也是并发运行。处理器运行每个线程一小段时间,并在线程之间切换来模拟并发执行。这使得每个线程看似都独立拥有自己的处理器。利用这一特性,你可以使得多个任务好像正在同时发生。实际上是在上下文(Context)切换到另外线程之前,每个线程只运行很短时间。


2.开发利用多处理器(Exploitation of Multiple Processors) ,资源利用率更好。


一些机器中有多个处理器。如果当前的操作系统和JVM的实现开发利用了多处理器,多线程的Java程序能实现真正的线程并发执行。而Java程序不需要修改,因为它已经用了线程。就像这些线程同时运行在不同的处理器上一样,它只能运行得更快。


串行,即按序执行每个线程的任务会使程序效率很低下,与之相对的是并行与并发。

并行是指多(核)cpu同时处理多个线程,每个cpu单独负责一个线程,有多少个cpu,就可以并行的执行多少线程。

而并发是指多个线程在宏观(相对于较长的时间区间而言)上表现为同时执行,

非并行的并发由一个cpu通过轮流执行每个线程的一部分来实现。


当等待慢的I/O操作时,可以做其他事情相对于处理器中的代码执行速度,对磁盘的输入输出操作,特别是跨网络的操作,速度相对来说是慢的。结果为了等待完成,读写操作可能被阻塞(block)相当长时间。

在java.io包中,类InputStream有一个read()方法会被阻塞,直到从流(stream)中读一个字节或者抛出一个IOException异常。当等待流上字节的到来时,执行该方法的线程不能做其他事情。如果创建了多线程,当某线程被阻塞后,其他线程就可以完成其他活动。


3.程序设计在某些情况下更简单。

4.程序响应更快。



3.线程的实现

线程是比进程更轻量级的调度执行单位,在linux里面,线程和进程没有什么区别,唯一的就是在地址空间,线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。

目前主流的操作系统都提供的线程实现,java则提供的线程实现方法都是native的,因为不同的硬件和操作系统提供线程调度方式并不尽相同,所以java没用采用和平台无关的统一手段来实现。

实现线程的主要3种方式:使用内核线程实现,使用用户线程实现,使用用户线程加轻量级进程混合实现。

内核线程实现

内核线程(KLT)就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换。

程序一般不会直接使用内核线程,而是去使用内核线程的一种高级接口—轻量级进程(LWP),轻量级进程就是我们所讲的线程,这种轻量级进程与内核线程之间1:1的对应关系。





优点:

内核直接支持,由操作系统内核创建和撤销。内核维护进程及线程的上下文信息以及线程切换。一个内核线程由于I/O操作而阻塞,不会影响其它线程的运行。

缺点:

1、线程的操作、创建、同步等都需要系统调用,而系统调用代价比较高,需要在用户态和内核态中来回切换。

2、每个轻量级的进程都需要一个内核线程来支持,需要消耗一定的内核资源。


用户线程实现


用户线程指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。

不需要用户态/核心态切换,速度快,操作系统内核不知道多线程的存在,因此一个线程阻塞将使得整个进程(包括它的所有线程)阻塞。使用用户线程实现的程序一般都比较复杂,java曾经用过,不过最后还是放弃了。

优点: 切换由用户态程序自己控制内核切换,不需要内核干涉,少了进出内核态的消耗。

缺点:多核处理器很难讲线程映射到其他处理器上,单线程阻塞会造成该进程阻塞。


用户线程加轻量级进程混合实现


这种混合模式下,既存在用户线程,也存在轻量级进程。用户线程还是完全建立在用户空间中,因此用户线程的创建、切换、析构等依然廉价,可以支持大规模的用户线程并发。

操作系统提供支持的轻量进程作为用户线程和内核线程之间的桥梁,用户线程的系统调用要通过轻量级线程来完成,大大降低了进程阻塞的风险。用户线程和轻量级进程比是N:M多对对的关系。




4.Java线程的实现

Java线程在JDK 1.2之前,是基于称为“绿色线程”(Green Threads)的用户线程实现的,
而在JDK 1.2中,线程模型替换为基于操作系统原生线程模型来实现。 因此,在目前的JDK版
本中,操作系统支持怎样的线程模型,在很大程度上决定了Java虚拟机的线程是怎样映射
的,这点在不同的平台上没有办法达成一致,虚拟机规范中也并未限定Java线程需要使用哪
种线程模型来实现。 线程模型只对线程的并发规模和操作成本产生影响,对Java程序的编码
和运行过程来说,这些差异都是透明的。
对于Sun JDK来说,它的Windows版与Linux版都是使用一对一的线程模型实现的,一条Java线程就映射到一条轻量级进程之中,因为Windows和Linux系统提供的线程模型就是一对一的。


而在Solaris平台中,由于操作系统的线程特性可以同时支持一对一(通过Bound Threads或Alternate Libthread实现)及多对多(通过LWP/Thread Based Synchronization实现)的线程模型,因此在Solaris版的JDK中也对应提供了两个平台专有的虚拟机参数 :-XX:+UseLWPSynchronization(默认值)和-XX:+UseBoundThreads来明确指定虚拟机使用哪种线程模型。


5.线程调度

线程调度主要是指系统为线程分配处理器使用权的过程,主要分为:协同式线程调度和抢占式线程调度。

协同式调度

协同式调度中线程的执行时间由线程本身来控制,线程把自己的工作执行完成以后,主动通知系统切换到另一个线程上。像lua的“协同历程”就是如此实现的。

优点: 实现简单,线程把自己的事情干完后进行线程切换,切换操作对线程自己是可知的。无同步问题

缺点: 线程执行时间不可控制,如果某个线程出现问题阻塞,会造成程序阻塞。

抢占式线程调度

抢占式线程调度中每个线程由系统来分配执行时间,线程的切换不由线程本身来决定。

优点: 线程的执行时间系统可控,不会出现单个线程阻塞造成整个进程阻塞。

java就是采用抢占式线程调度,另外,java还可以通过给线程设置优先级来建议系统给某些线程多分配一点时间,不过不是很靠谱,线程的调度最终还是取决的操作系统。



更多相关文章

  1. java多线程jdk1.7与jdk1.6结果不一致的问题
  2. Java线程的生命周期和状态控制
  3. 使用线程设置后台进程以处理Android中的工作
  4. Android开发之线程与线程池
  5. Android多线程下载远程图片【转】
  6. 理解Android的本地Service和跨进程Service
  7. android init进程分析 ueventd — 设备节点的创建、固件更新过
  8. Android学习笔记(三一):线程:Message和Runnable
  9. Linux上杀死eclipse进程

随机推荐

  1. IT兄弟连 JavaWeb教程 文件上传技术
  2. 读取Excel文件并跳过空行但不是空列
  3. Spring MVC-集成(Integration)-集成LOG4J示
  4. 有关JavaScript的认识
  5. Java将一个字符串中的多个连一起的空格变
  6. Java提高篇——equals()方法和“==”运算
  7. javascript 基础知识点
  8. 关于Javascript中声明变量、函数的笔记
  9. 如何在Spring Data(JPA)派生查询中按多个属
  10. Java设计模式-策略模式