并发概要

前言

如果你跟我一样,写了一两年的顺序编程,即程序中的所有事物在任何时刻都只能执行一个步骤,那么你应该考虑学习一下并发高级技术。

并发很难,精通并发编程的学习难度基本和精通面向对象编程差不太多,我自己也处在一个学习阶段,所以如果你看了这篇博客可能错误不少,不过没有关系,学习本身就是面向未知,在黑暗中探索。

何为并发

如果你是一个JAVA的使用者,你肯定知道通过复写Runnable接口,在Thread构造方法中New一个Runnable对象,通过start方法便可启用一个线程,并发可以简单的理解为多线程编程。如果你学过操作系统熟悉进程,线程的概念,想必你很清楚并发。可是我们在日常编程中很少使用并发,因为它很难。为何我不断强调它很难,本质上讲:并发"具有可论证的确定性,但是实际上具有不可确定性"。这句话很绕对不对?其实我也不太懂。

为何我们要学习并发

客观原因有一:通过并发线程可以使程序执行得到极大提高,简单说就是可以更多的压榨计算机的性能。当前的摩尔定律多多少少有些过时了,速度的提升更多是以多核cpu的形式而不是速度更快的芯片的形式出现(对,就是日常场景出现的四核八核手机)。

  1. 提高运行在单处理器的程序性能

    此话听起来有点违背直觉,因为并发在单处理器上的运行开销确实比所有程序都顺序执行的开销要大,因为其中增加了所谓上下文切换的代价。问题的核心在于"堵塞",在编程中难免要与I/O操作,网络请求操作导致整个程序停下来,直到外部条件改变。如果使用并发编写程序,那么当其中一个程序阻塞时,程序中的其他程序还可以继续进行。从单核处理器来讲,如果没有任务阻塞,那么在单核cpu也就没有所谓的并发编程。

  2. 事件驱动的编程

    想要编写出流畅的具有可响应界面的用户界面,并发必不可少。考虑一下这样的场景,因为程序在执行某段长期运行的操作,导致用户输入会被忽略掉,从而称为不可响应的程序。如果不使用并发来处理,那么可以产生可响应用户界面的唯一方法就是所有任务都周期性检查用户输入。当我们通过单独创建的执行线程来响应用户的输入,即使这个线程在大多数时间都是阻塞的,但是程序具有一定程度的可响应性。

基本的线程机制

并发编程让我们可以让程序划分为多个分离的.独立运行的任务。通过使用多线程机制,这些独立任务的每一个都由执行线程来驱动。一个线程在进程中是 单一的顺序控制流。单个进程可以拥有多个并发执行的任务,但是你的程序使得每个任务都好像有自己的CPU。

  1. Runnable接口

    public class LiftOff implements Runnable {
        protected int countDown = 10;
    
        private static int taskCount = 0;
    
        private final int id = taskCount++;
    
        public LiftOff() {
    
        }
    
        public LiftOff(int countDown) {
            this.countDown = countDown;
        }
    
        @Override
        public void run() {
            while (countDown-- > 0) {
                System.out.println(status());
                Thread.yield();
            }
        }
    
        public String status() {
            return "#" + id + "(" + (countDown > 0 ? countDown : "Liftoff") + ").";
        }
    
    }
    

    任务的run方法通常写为某种形式的循环,使任务一直运行下去直到不在需要。通常run方法被写成了无限循环的形式。通常我们会中断线程来结束任务。

  2. Thread类

    Thread类通过构造方法需要一个Runnable对象,调用Thread类的start方法来执行必要的初始化操作,然后调用Runnable的run方法。

  3. 使用Executor

    在java1.5后引入了java,util.concurrent包中的执行器将为接管Thread对象简化了并发的编程,Executor允许管理异步任务的执行,ExecutorService知道如何构建恰当的上下文执行Runnable对象。

    • newCacheThreadPool

      创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

    • newFixThreadPool

      创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

    • newSingleThreadExecutor

      创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

    • newScheduledThreadPool

      创建一个定长线程池,支持定时及周期性任务执行。

  4. Callable

    Runnable是执行工作的独立任务,但是它不返回任何值,如果希望任务完成返回一个值,那么可以实现Callable接口而不是Runnable接口,它的类型参数表示的是从方法call(),并且使用ExecutorService.submit()方法调用它。submit方法会产生Future对象,它用Callable返回结果的特定类型。

  5. 后台线程

    所谓后台线程也成 守护线程,是指程序运行的时候在后台提供一种通用服务的线程,并且这种线程并不属于程序不可或缺的部分。因此当所有的非后台线程结束,程序也就终止了,同时会杀死进程的所有后台程序。必须在线程启动前调用setDaemon()方法,才能把它设置为后台线程。

  6. 基本总结

    在我开始接触并发的时候,十分疑惑在于,所要执行的任务和去动它的线程是有差异的。Thread类自身不执行任何操作,他只是驱动赋予它的任务。其实我们对于Thread类没有任何的控制,你只能创建任务,通过某种方式将一个线程附着到任务,来使得这个线程可以驱动任务。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,560评论 18 399
  • 一.线程安全性 线程安全是建立在对于对象状态访问操作进行管理,特别是对共享的与可变的状态的访问 解释下上面的话: ...
    黄大大吃不胖阅读 822评论 0 3
  • 忘了是什么时候,有人告诉我:你知道吗,我一直觉得你与我们保持距离,有时候,我们总觉得你在另一个跟我们不一样的世界。...
    时间给的温柔阅读 414评论 2 2
  • 面对困难,你是选择逃避?还是选择相信自己? 今天的晨读材料给我们分享了能力要用“将来进行时”。讲个真实的故事。 我...
    一米Sunny阅读 441评论 0 1