对编程语言的基础知识:分支、选择、循环、面向对象等基本概念理解后,我们需要对java高级编程有一定的学习,这里不可避免的要接触到多线程开发。

由于多线程开发整体的系统比较大,我会写一个系列的文章总结介绍 多线程开发的概念、使用、线程状态、同步、线程池。希望与大家共勉。

在第一部分,也就是本节我们先介绍下 什么是多线程程序、线程和进程又是什么,以及为什么要搞多线程。


(一)什么是多线程程序

多线程听上去是非常专业的概念,其实非常简单,我们在日常生活中,经常的接触到多线程。

比如

(1)在工厂,工人努力工作,分工明确。一些工人准备生产资料(混凝土、钢筋、砖头),另外一些工人挖掘地基,还有些工人负责平常无聊的看管,后勤的保障(有点像守护进程,这个后面会专门讲到)。他们总体来说就是把一件事分成若干的工作,然后派不同的人去做,最后使工作得到完善的解决。(一个工人算一条线程)

(2)一个学生完成晚上写的作业,有语、数、外的作业。这名学生写了一半的语文作业后,有一道题不会做,先去完成数学作业,接着再完成英语作业,最后等到家长回来完成语文作业。(一门作业算一条线程)

主要是有这两种情况的多线程,

一种是上边有多个工人(多处理器),各个工人间的工作影响不大,不会因为其中一个工人的努力工作,而导致另外一个工作停歇。

另外一种就是下边的写作业形式(单处理器,只有一个人在做作业),虽然我们有多个作业需要在今天晚上完成(执行),但是某一个时刻我们只能做一件事,当遇到某种情况(例如不会做、或者心情不好)我们随意的切换到其他的科目,然后开始其他的工作,因为某些原因(如有人可以出现辅导),那么我们又可以切换回来,继续做一开始未完成的事情,直到所有的事情都解决完为止。这里要区分一下:写作业的例子看着有点像单线程模式的例子,实则不然,单线程只能按照某种既定的顺序,顺序完成事情,比如语文->外语->数学。遇到困难时(不会做),并不能因为某种原因,而随意的切换,只能苦苦等待。而多线程则可根据环境动态的转换,如他们之间的顺序如语文->外语->数学->语文->外语->外语->数学 这样。(防盗连接:本文首发自王若伊_恩赐解脱http://www.cnblogs.com/jilodream/ )

这种一次做多件事的情况就是多线程(包含短时间内快速的切换,形成一次做多件事的感觉),下面介绍进程和线程,从计算机的角度来谈谈编程中多线程的概念。


(二)线程和进程又是什么

进程: 对于一个OS,如果有一个程序在内存中开始运行,我们就可以说这个运行的程序就是一个进程。这个进程拥有自己独立的功能,并且是OS调度和分配资源的一个独立单位。

对于进程有三个特点

(1)独立性:进程是系统中独立存在的一个实体,拥有自己的资源的,没有自身的允许的话,其他用户进程是不能访问他内部的。

(2)动态性:进程是有生命周期的,他是在OS中活动的一个指令集合。而程序只是一个静态的指令集合。

(3)并发性:在只有一个处理器时,多个进程间也可以并发执行,互相并不影响。(进程间相互轮换执行,如同同时进行一般)

线程:线程是进程执行单元,也可以说是一个轻量级的进程。就像OS中进程是独立的一样,进程中的各个线程也是独立的。每个线程都有自己独立的堆栈及其他资源。互相并不受影响。而进程(这些线程的拥有者)的所有系统资源,被它包含的所有线程所共有分享。

线程也是独立的,他并不知道当前进程中其他线程的存在,而当前线程是否被执行,则与进程类似,是抢占式的。当前进程抢到了OS的执行权,而进程中的某一条线程又抢到了,当前可执行的权利(其他线程和进程被挂起)。

多线程就是一个进程中,可以有多个并发执行的独立的任务,每一个任务可以说就是一个线程。

他们的关系:

一个OS下边可以有若干的进程(但是至少要有一个进程)。

每一个进程下边又有若干的线程(至少要有一条线程)。


(三)为什么要搞多线程呢?

最最最核心的原因就是:提高工作效率,不要出现闲时等待,各个线程抢占式的工作。试想下,如果我们遇到什么问题,是应该一直苦苦等待(是什么都不做的等待)下去性能高呢,还是快速的切换到其他工作上去,我想在大部分的情况下都是快速抢占吧。(有时可能会出现,你刚刚切换,原来苦苦等待的事情刚刚结束。。。。这种碰巧的情况),举个实际点的例子,当我们查询某一个数据时,这个数据可能非常大,我们需要等待好久才能在页面上加载下来,此时倘若单线程苦苦等待时,我们的程序就是被挂死了(试想下没有响应的场景),直到过去了很久,页面才被激活,变成可用的状态。这期间我们什么事情也干不了(对该程序),这时的场景效率很低下,而且非常不友好。

  倘若有很好的多线程支持的话,那么在加载数据、绘制图片时,我们还可以随意的切换程序,并不影响其他的操作,从而提高性能。于此同时,由于多线程共享父进程的其他所有资源,所以线程间可以很好的交流数据(数据共享和通信),并且新开辟的线程(新开辟的任务),OS并不会为该进程分配大量的资源(相对于为新开辟任务而创建新进程而言)。

总结一下有如下几个优点

1、线程间可以很好的共享内存资源,进程间是完全独立内存的,所以不方便。(前文中提到线程间是相互独立的,除非一进程允许,否则其他的进程是不允许直接访问它地址的)

2、系统创建新线程的开销,新创建进程的开销要小的多,因此可大大降低多并发的代价。

3、在编码时,我们可以通过类库和代码很好的管理各个线程,而不是直接通过操作系统来指挥当前执行的进程。从而大大的方便了我们可以处理并发任务的执行。

Java多线程开发系列之一:走进多线程的更多相关文章

  1. Java多线程开发系列之番外篇:事件派发线程---EventDispatchThread

    事件派发线程是java Swing开发中重要的知识点,在安卓app开发中,也是非常重要的一点.今天我们在多线程开发中,穿插进来这个线程.分别从线程的来由.原理和使用方法三个方面来学习事件派发线程. 一 ...

  2. Java多线程开发系列之四:玩转多线程(线程的控制2)

    在上节的线程控制(详情点击这里)中,我们讲解了线程的等待join().守护线程.本节我们将会把剩下的线程控制内容一并讲完,主要内容有线程的睡眠.让步.优先级.挂起和恢复.停止等. 废话不多说,我们直接 ...

  3. Java多线程开发系列之三:线程这一辈子(线程的生命周期)

    前文中已经提到了,关于多线程的基础知识和多线程的创建.但是如果想要很好的管理多线程,一定要对线程的生命周期有一个整体概念.本节即对线程的一生进行介绍,让大家对线程的各个时段的状态有一定了解. 线程的一 ...

  4. 高级java必会系列二:多线程经常使用的3个关键字:synchronized、ReentrantLock、volatile

    系列一讲解了多线程,本章讲解多线程开发中经常使用到的3个关键字synchronized.ReentrantLock.volatile. 一.synchronized 互斥锁,即操作互斥,并发线程过来, ...

  5. Java SE开发系列-JDK下载安装

    JDK下载安装 JDK是Java的开发环境,目前JDK内部也包含了JRE,JRE主要是JAVA程序的运行环境. 点击官方下载地址,按着下图操作即可下载对应系统的不同版本JDK. 进入页面滑到页面底部点 ...

  6. Java多线程开发系列之二:如何创建多线程

    前文已介绍过多线程的基本知识了,比如什么是多线程,什么又是进程,为什么要使用多线程等等. 在了解了软件开发中使用多线程的基本常识后,我们今天来聊聊如何简单的使用多线程. 在Java中创建多线程的方式有 ...

  7. Java多线程开发系列之四:玩转多线程(线程的控制1)

    在前文中我们已经学习了:线程的基本情况.如何创建多线程.线程的生命周期.利用已有知识我们已经可以写出如何利用多线程处理大量任务这样简单的程序.但是当应用场景复杂时,我们还需要从管理控制入手,更好的操纵 ...

  8. Java多线程开发系列之五:Springboot 中异步请求方法的使用

    Springboot 中异步线程的使用在过往的后台开发中,我们往往使用java自带的线程或线程池,来进行异步的调用.这对于效果来说没什么,甚至可以让开发人员对底层的状况更清晰,但是对于代码的易读性和可 ...

  9. 高级java必会系列一:多线程的简单使用

    众所周知,开启线程2种方法:第一是实现Runable接口,第二继承Thread类.(当然内部类也算...)常用的,这里就不再赘述.本章主要分析总结线程池和常用调度类. 一.线程池 1.newCache ...

随机推荐

  1. 洛谷 P1736 创意吃鱼法 Label:dp || 前缀和

    题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...

  2. DB2数据库参数建议(Linux)

    内核参数配置: kernel.shmall=<物理内存的90%,以页为单位> kernel.shmax=<实际的物理内存> kernel.shmmni= kernel.msgm ...

  3. CSS居中布局总结【转】

    居中布局 <div class="parent"> <div class="child">demo</div> </d ...

  4. MATLAB基础知识之内存映射

    如果我们的文件太大而不能一次性加载进内存,我们可以创建一个memmapfile对象,这样可以将原始数据当做数组一样来访问,并且同样的通过下标访问数据. 用MNIST数据()举个例子: [Xtrain, ...

  5. Git fetch和git pull的区别

    Git中从远程的分支获取最新的版本到本地有这样2个命令:1. git fetch:相当于是从远程获取最新版本到本地,不会自动merge git fetch origin mastergit log - ...

  6. 【30集iCore3_ADP出厂源代码(ARM部分)讲解视频】30-3 底层驱动之LED_蜂鸣器

    视频简介: 该视频介绍iCore3应用开发平台出厂源代码中GPIO的配置方法 及如何点亮LED和驱动蜂鸣器发声. 源视频包下载地址: http://pan.baidu.com/s/1nvpYMff   ...

  7. 总结-html

    页面尺寸: var w = document.body.scrollWidth; (w + "px")var h = document.body.scrollHeight; (h ...

  8. netfiler源代码分析之框架介绍

    netfiler框架是在内核协议栈实现的基础上完成的,在报文从网口接收,路由等方法实现基础上使用NF_HOOK调用相应的钩子来进入netfiler框架的处理,如 ip_rcv之后会调用NF_HOOK( ...

  9. 非常适用的Sourceinsight插件,提高效率事半功倍

    一直使用sourceinsight编辑C/C++代码,sourceinsight是一个非常好用的编辑工具可以任意定位,跳转,回退,本人一直 使用该工具做C/C++开发,sourceinsight能够满 ...

  10. Elong App 性能测试分享

    个人简介: 测试老鸟,曾做过6年的测试以及2年的大数据开发:曾就职于伟景行.高德(大数据开发):钟情于钻研开源测试框架:目前挂单于艺龙. 有对本主题感兴趣的同学,可以加我Q私信(305285925): ...