美文网首页
Java编程思想之多线程(一)

Java编程思想之多线程(一)

作者: 码头军 | 来源:发表于2018-09-09 03:29 被阅读0次

    多线程技术是个很庞大的课题,《Java编程思想》这本书(英文版,以下简称TIJ)中也用了136页介绍Java的多线程体系。的确,Java语言发展到今天,多线程机制相比其他的语言从稳定性,API的丰富度上绝对是数一数二的了。TIJ从Java语言的视角向我们展示了如何高效、正确地使用java api,但同时又不失普遍性,其中介绍的变量的原子性(atomicity)、可见性(visibility),多线程的资源竞争(resource contention),线程中断(interruption),线程之间的协作(cooperation),多线程编程的一些实践法则等对其他语言的程序员也具有很高的参考意义。

    但限于篇幅,TIJ并未从操作系统的角度对线程作更多更深入的介绍,本系列文章试着由底向上,1)从操作系统的角度来理解线程,2)从JVM的层面来学习线程,3)借助其他语言的多线程机制来对比深入、熟练底掌握Java多线程编程。

    本篇先从底层操作系统的视角重温下线程相关的理论知识。

    一、引入线程(thread)的目的

    “同步”执行多个任务,提高资源使用效率,提升任务执行速率。“同步”在单CPU环境下是个模拟并行的过程;在多CPU和多核CPU场景下,能够真正并行执行。单CPU场景下通过线程模拟多任务并行执行;充分利用硬件资源,例如:读取/写入文件或网络,可由不同的CPU、不同的CPU核并行执行。见图一。

    Java编程思想之多线程(一)

    图一:单线程与多线程

    当然,引入多线程后,相应就要增加线程的调度(thread scheduling),上下文切换(context switching),额外的储存空间(例如:线程栈,线程控制区等)。

    二、进程(process)的定义

    进程是程序(Program)在操作系统(Operation system)上的一次执行,它有自己的虚拟地址空间。例如:运行一个java程序,打开IDE,操作系统都会为我们生成一个或多个进程。

    三、线程的定义

    线程是进程的一个子集,是进程中的一段代码。一个线程包括代码段(code segment)、数据段(data segment)、寄存器(registers)、程序计算器(PC,program counter)、栈指针(SP,stack pointer)和线程控制区(TCB,Thread Control Block,存储thread context,包括线程的PC,Register,SP等的数据结构),上述数据结构和进程类似,因此线程也被称为轻量级进程(LWP,lightweight process)。

    四、进程与线程之间的关系

    进程必需要有一个线程,而且该线程是一个内核线程(kernel thread)(因为kernel调度的往往是线程)。该线程也是进程启动时创建的第一个线程。而进程的运行,实际上是进程中的线程在运行,进程只不过为线程提供了进程地址空间(process address space),各种资源(file handler,socket等)。从这个角度来讲进程也是一个线程,一个为其他线程服务的线程。

    TGID: thread group id也是进程中第一个线程的id,即TID。利用fork或vfork或clone可以创建一个新的线程,如果不带参数CLONE_THEAD,系统会创建一个新的线程,分配新的TID,这个TID也是新的TGID,而这个线程也是一个新的进程。如果带有参数CLONE_THEAD,则会在当前进程中创建一个新的线程,分配新的TID,而该线程的TGID和创建改线程的TGID保持一致。

    一个线程归属于唯一的进程,线程无法脱离进程而存在。一个进程中的多个线程共享相同的进程空间,代码段,数据段。见图二。

    Java编程思想之多线程(一)

    图二:多线程进程

    五、线程内数据

    线程的私有数据:仅归属于一个线程,不在线程之间共享,例如:PC,Stack,CP。

    线程的共有数据:程序代码;全局变量;heap。

    六、线程种类

    内核线程(kernel thread):顾名思义,内核线程运行在kernel的进程空间,由kernel负责创建,分配进程空间,创建TCB;线程之间的调度,线程的销毁等也都运行在内核中。见图三。

    Java编程思想之多线程(一)

    图三:内核线程(摘自:https://www.inf.ed.ac.uk/teaching/courses/os/slides/04-thread17.pdf)

    用户线程(user-level thread):用户线程对kernel来说是透明的,也就是kernel并不知道用户线程的存在。见图四。

    Java编程思想之多线程(一)

    图四:用户线程(摘自:https://www.inf.ed.ac.uk/teaching/courses/os/slides/04-thread17.pdf)

    由图四可以看出用户线程通过内核线程来执行任务。而内核线程和用户线程都有哪些关系?用户线程如何映射到内核线程?程序(program)和进程关系又是怎样的?在下一篇详细介绍。关注公众号“码农走向艺术”获取最新原创文章。

    码头军

    相关文章

      网友评论

          本文标题:Java编程思想之多线程(一)

          本文链接:https://www.haomeiwen.com/subject/bulrgftx.html