Java多线程学习(一)---并发与多线程

Java并发与多线程

摘要:算法

1. 并发与并行的区别,何为并发编程,并发编程的优点在哪编程

2. 多线程、多任务、多进程机制概述浏览器

3. 多线程、多任务、多进程机制与编程思想的关系服务器

1、并发

1.1 并发与并行

首先介绍一下并发与并行,二者虽然只有一字之差,但实际上却有着本质的区别,其概念以下:多线程

并行性(parallel):指在同一时刻,有多条指令在多个处理器上同时执行;架构

并发性(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,使得在宏观上具备多个进程同时执行的效果。并发

1.2 顺序编程与并发编程

咱们在解决编程问题时,一般使用顺序编程来解决,即程序中的全部事物在任意时刻都只能执行一个步骤。然而对于某些问题,咱们但愿可以并行地执行程序中的多个部分,来达到咱们想要的效果。在单处理器机器中,咱们能够将程序划分为多个部分,而后每一个部分由该处理器并发执行。在多处理器机器中,咱们能够将程序划分多个部分,而后每一个部分分别在多个处理器上并行执行。固然为了更加充分利用CPU资源,咱们也能够在多个处理器上并发执行,那么在这咱们就涉及到了另外一种编程模式了并发编程。并发编程又叫多线程编程。并发编程使咱们能够将程序划分为多个分离的、独立运行的任务。经过使用多线程机制,每一个独立任务都将由线程来驱动。一个线程就是在进程中的一个单一的顺序控制流,单个进程能够拥有多个"并发执行"的任务。这样使程序的每一个任务,都好像拥有一个本身的CPU同样。但其底层机制仍是是切分CPU时间,CPU都有个时钟频率,表示每秒中能执行CPU指令的次数。在每一个时钟周期内,CPU实际上只能去执行一条也有可能多条指令。操做系统将进程进行管理,轮流分配每一个进程很短的一段是时间但不必定是均分,而后在每一个进程内部,程序代码本身处理该进程内部线程的时间分配,多个线程之间相互的切换去执行,这个切换时间也是很是短的因此一般咱们不须要考虑它。负载均衡

并发是指"发",不是处理,最多见的状况就是许多人在一小段时间内都点击了你的网站,发出了处理请求。并发编程是对并发情况的应对,在单处理器和多处理器机器上均可对其进行应对,可这个处理方案和架构以及算法有关。CPU通常是分时的,会在极短的时间内不停地切换给不一样的线程使用,不管多少并发都会处理下去,只是时间问题,如何提升处理效率就看采用的技术了。性能

1.3 并发编程的优点

并发编程可使咱们的程序执行速度获得提升,例如,若是你有一台多处理器的机器,那么就能够在这些处理器之间分布多个任务,从而能够极大地提升吞吐量。这是Web服务器的常见状况,通常Web服务器是一个多处理器机器,将为每一个请求分配到一个线程中,那么就能够将大量的用户请求分布到多个CPU上进行并发处理。网站

可是,并发一般是提升运行在单处理器上的程序的性能。虽然,在单处理器上运行的并发程序开销确实应该比该程序的全部部分都顺序执行开销,由于其中增长了所谓上"下文切换"的代价,即从一个任务切换到另外一个任务。表面上看,将程序的全部部分看成单个的任务运行好像是开销更小一点,而且能够节省上下文切换的代价。可是咱们的程序并不会按咱们设想的那样一直正常运行,它会发生阻塞。若是程序中的某个任务由于某些缘由发生了阻塞,那么该任务将不能继续执行。若是没有并发,则整个程序都将中止下来,直至外部条件发生变化。可是,若是使用并发来编写程序,那么当一个任务阻塞时,程序中的其余任务还能够继续执行,所以这个程序能够保持继续向前执行,这样就提升程序的执行效率和运行性能。

并发须要付出代价,包含复杂性代价,可是这些代价与在程序设计、资源负载均衡以及用户方便使用方面的改进相比,就显得微不足道了。一般,线程使你可以建立更加松散耦合的设计则,你的代码中各个部分都必须显式地关注那些一般能够由线程来处理的任务。

2、多任务、多进程、多线程

几乎全部的操做系统都支持同时运行多个任务,一个任务一般就是一个程序,每一个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每一个顺序执行流就是一个线程

2.1 多进程

实现并发最直接的方式是在操做系统级别使用进程,进程是运行在它本身的地址空间内的自包容的程序。多任务操做系统能够经过周期性地将CPU从一个进程切换到另外一个进程,来实现同时运行多个进程。 尽管对于一个CPU而言,它在某个时间点只能运行一个进程,但CPU能够在多个进程之间进行轮换执行,而且CPU的切换速度极高,使咱们没法感知其切换的过程,就好像有多个进程在同时执行。

几乎全部的操做系统都支持进程的概念,全部运行中的任务一般对应一个进程(Process)。当一个程序进入内存运行时,即变成一个进程。进程是处于运行过程当中的程序,而且具备必定的独立功能,进程是系统进行资源分配调度的一个独立单位。通常而言,进程包含以下3个特征

独立性:进程是系统中独立存在的实体,它能够拥有本身独立的资源,每个进程都拥有本身私有的地址空间。在没有通过进程自己容许的状况下,一个用户进程不能够直接访问其余进程的地址空间。

动态性:进程与程序的区别在于,程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合。在进程中加入了时间的概念,进程具备本身的生命周期和各类不一样的状态,这些概念在程序中部是不具有的。

并发性:多个进程能够在单个处理器上并发执行,多个进程之间不会互相影响。

现代的操做系统都支持多进程的并发,但在具体的实现细节上可能由于硬件和操做系统的不一样而采用不一样的策略。比较经常使用的方式有:共用式的多任务操做策略,例如Windows 3.1和Mac OS 9。目前操做系统大多采用效率更高的抢占式多任务操做策略,例如 VVindows NT、Windows 2000以及UNIX/Linux等操做系统。但对进程的并发一般会有数量和开销的限制,以免它们在不一样的并发系统之间的可应用性。为了应对该问题,因此在多进程的基础上提出了多线程的概念,下面将详细介绍。

2.2 多线程

2.2.1 多线程概述

多线程则扩展了多进程的概念。使得同一个进程中也能够同时并发处理多个任务。线程(Thread)也被称做轻量级进程(Lightweight Process)。线程是进程的执行单元,就像进程在操做系统中的地位同样,线程在程序中是独立的、并发的执行流。当进程被初始化后,主线程就被建立了。对于绝大多数的应用程序来讲,一般仅要求有一个主线程,但也能够在该进程内建立多条顺序执行流,这些顺序执行流就是线程,每一个线程也是互相独立的。

线程是进程的组成部分,一个进程能够拥有多个线程,一个线程必须有一个父进程。线程能够拥有本身的堆栈、本身的程序计数器和本身的局部变量,但不拥有系统资源,它与父进程的其余线程共享该进程所拥有的所有资源。由于多个线程共享父进程里的所有资源,所以编程更加方便;但必须更加当心,咱们必须确保线程不会妨碍同一进程里的其余线程。

2.2.2 多线程机制

线程模型为编程带来了便利,它简化了在单一程序中同时交织在一块儿的多个操做的处理。在使用线程时,CPU将轮流给每一个任务分配其占用时间。每一个任务都以为本身在一直占用CPU,但事实上CPU时间是划分红片断分配给了全部的任务。线程的一大好处是可使你从这个层次抽身出来,即代码没必要知道它是运行在具备一个仍是多个CPU的机器上。因此,使用线程机制是一种创建透明的、可扩展的程序的方法,若是程序行得太慢,为机器增添一个CPU就能很容易地加快程序的运行速度。多任务和多线程每每是使用多处理器系统的最合理方式。

2.2.3 多线程调度

线程能够完成必定的任务,能够与其余线程共享父进程中的共享变量部分环境,相互之间协同来完成进程所要完成的任务。线程是独立运行的,它并不知道进程中是否还有其余线程存在,线程的执行抢占式的,也就是说,当前运行的线程在任什么时候候均可能被挂起,以便另一个线程能够运行。

一个线程能够建立和撤销另外一个线程,同一个进程中的多个线程之间能够并发执行。从逻辑角度来看,多线程存在于一个应用程序中,让一个应用程序中能够有多个执行部分同时执行,但操做系统无须将多个线程看做多个独立的应用,对多线程实现调度和管理以及资源分配。线程的调度管理进程自己负责完成。

概括起采能够这样说:操做系统能够同时执行多个任务,每一个任务就是进程;进程能够同时执行多个任务,每一个任务就是线程。简而言之,一个程序运行后至少有一个进程,一个进程里能够包含多个线程,但至少要包含一个线程。

2.2.4 多线程的优点

线程在程序中是独立的、并发的执行流,与分隔的进程相比,进程中线程之间的隔离程度要小

01. 它们共享内存文件句柄和其余每一个进程应有的状态。由于线程的划分尺度小于进程,使得多线程程序的并发性高。进程在执行过程当中拥有独立的内存单元,而多个线程共享内存,从而极大地提升了程序的运行效率

02. 线程比进程具备更高的性能,这是因为同一个进程中的线程都有共性----多个线程共享同一个进程虚拟空间。线程共享的环境包括进程代码段进程的公有数据等。利用这些共享的数据,线程很容易实现相互之间的通讯

03. 当操做系统建立一个进程时,必须为该进程分配独立的内存空间,并分配大量的相关资源;但建立一个线程则简单得多,所以使用多线程来实现并发比使用多进程实现并发的性能要高得多

总结起来,使用多线程编程具备以下几个优势:

01. 进程之间不能共享内存,但线程之间共享内存很是容易

02. 系统建立进程时须要为该进程从新分配系统资源,但建立线程则代价小得多,所以使用多线程来实现多任务并发比多进程的效率高

03. Java语言内置了多线程功能支持,而不是单纯地做为底层操做系统的调度方式,从而简化了Java的多线程编程

在实际应用中,多线程是很是有用的,一个浏览器必须能同时下载多个图片;一个Web服务器必须能同时响应多个用户请求;Java虚拟机自己就在后台提供了一个超级线程来进行垃圾回收;图形用户界面(GUI)应用也须要启动单独的线程从主机环境收集用户界面事件……总之,多线程在实际编程中的应用是很是普遍的。

若是,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
若是,您但愿更容易地发现个人新博客,不妨点击一下左下角的【关注我】。
若是,您对个人博客所讲述的内容有兴趣,请继续关注个人后续博客,我是【Sunddenly】。

本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然保留追究法律责任的权利

相关文章
相关标签/搜索