首页 > 代码库 > Java并发编程:进程和线程

Java并发编程:进程和线程

<style type="text/css">.title { text-align: center } .todo { font-family: monospace; color: red } .done { color: green } .tag { background-color: #eee; font-family: monospace; padding: 2px; font-size: 80%; font-weight: normal } .timestamp { color: #bebebe } .timestamp-kwd { color: #5f9ea0 } .right { margin-left: auto; margin-right: 0px; text-align: right } .left { margin-left: 0px; margin-right: auto; text-align: left } .center { margin-left: auto; margin-right: auto; text-align: center } .underline { text-decoration: underline } #postamble p,#preamble p { font-size: 90%; margin: .2em } p.verse { margin-left: 3% } pre { border: 1px solid #ccc; padding: 8pt; font-family: monospace; overflow: auto; margin: 1.2em } pre.src { position: relative; overflow: visible; padding-top: 1.2em } pre.src::before { display: none; position: absolute; background-color: white; top: -10px; right: 10px; padding: 3px; border: 1px solid black } pre.src:hover::before { display: inline } pre.src-sh::before { content: "sh" } pre.src-bash::before { content: "sh" } pre.src-emacs-lisp::before { content: "Emacs Lisp" } pre.src-R::before { content: "R" } pre.src-perl::before { content: "Perl" } pre.src-java::before { content: "Java" } pre.src-sql::before { content: "SQL" } table { border-collapse: collapse } caption.t-above { caption-side: top } caption.t-bottom { caption-side: bottom } td,th { vertical-align: top } th.right { text-align: center } th.left { text-align: center } th.center { text-align: center } td.right { text-align: right } td.left { text-align: left } td.center { text-align: center } dt { font-weight: bold } .footpara:nth-child(0n+2) { display: inline } .footpara { display: block } .footdef { margin-bottom: 1em } .figure { padding: 1em } .figure p { text-align: center } .inlinetask { padding: 10px; border: 2px solid gray; margin: 10px; background: #ffffcc } #org-div-home-and-up { text-align: right; font-size: 70%; white-space: nowrap } textarea { } .linenr { font-size: smaller } .code-highlighted { background-color: #ffff00 } .org-info-js_info-navigation { border-style: none } #org-info-js_console-label { font-size: 10px; font-weight: bold; white-space: nowrap } .org-info-js_search-highlight { background-color: #ffff00; color: #000000; font-weight: bold }</style> <style type="text/css">code { color: #FF0000 } pre.src { background-color: #002b36; color: #839496 }</style>

Java并发编程:进程和线程

Table of Contents

  • 1. 什么是进程?
  • 2. 什么是线程?
  • 3. 为什么会有进程和线程?
  • 4. 差异

1 什么是进程?

如果我们使用过任务管理器就知道进程是什么了。我们每次打开一个程序,必定会创建一个新的进程。

技术分享

PID就是进程的ID,一个程序会对应一个进程ID。

2 什么是线程?

如上图,除了PID之外,还有一项 线程 ,线程是在进程里面工作的,比如Emacs进程PID是20,线程数为7,就是在Emacs中还运行了7个线程。现在就只需要了解这个概念就可以了,后面,还要进行详细的解释。

3 为什么会有进程和线程?

在最早的操作系统中,是只有一个程序可以工作的,相当于是单进程的系统。比如,我们现在在听歌,但是想查看一下邮件,那么,需要先把听歌程序结束掉。觉得不可思议啊,最早期的操作系统就是单任务的。后来,为了实现系统程序的并发运行,做了时间的分片处理。就是CPU可能还是一个,但是,把CPU的运行时间单元划分成很小的时间片,每个程序分配一个时间片运行一下。由于时间片很短,程序的数量又有限,所以,每隔很短的一段时间,CPU就会把所有的程序遍历一遍。CPU的速度是GHz等级的,所以,我们根本觉察不出来,感觉所有的程序是同时运行的。实际上,严格的同一时刻只有一个程序在运行。所以,进程使不同的程序并发运行成为可能。
那么,为什么会有线程呢?线程是在进程里面的,就是我一个程序,比如,听歌软件,一方面它要播放音乐,同时,它可能还要下载其他歌曲,或者更新歌词。难道,我们必须要下载完,播放,关掉播放,再去下载吗?当然,那是我们无法忍受的。所以,在同一个程序里面实现不同的任务,我们就用线程来实现了。

所以,总的来说,操作系统中可能有多个进程,每个进程里面可能有多个线程,至少有一个主线程。进程是系统分配资源的单位,线程是系统分配时间的单位。就是说,我们每次创建一个进程的时候,就会为这个进程分配一定的内存空间。线程是属于进程的,所以,它可以访问进程的所有内存空间,就是多个线程共享进程的内存空间。系统根据线程的数量进行时间片的分配。

4 差异

进程和线程都是实现任务的并发而创建的,那么,它们的差异是怎样的,以及什么时候用进程,什么时候用线程呢?
虽然,它们都可以实现并发。但它们创建的开销以及通讯的成本是不一样的。当它们是不同的程序的时候,肯定是不同的进程,因为程序可能是别人写的,你想要做成线程也不可能。当自己编写的程序的时候,如果我们想把某个功能做成独立的模块,供不同的程序调用,那么我们会把它实现为一个新的程序。当只在程序内部使用,并且需要访问当前程序中的资源时,则可以实现为线程,方便资源的共享。但涉及到多线程,以及并发访问同一个资源时,则会涉及到同时访问和修改同一个变量,数据的同步和一致性等问题,这个也是多线程编程里面最麻烦的地方,多线程的复杂度和出问题的可能性也比单线程要高很多,这个我们后面再慢慢的讲解了。

Date: 2017-07-02 21:10

Author: WEN YANG

Created: 2017-07-03 Mon 21:23

Emacs 25.2.1 (Org mode 8.2.10)

Validate

Java并发编程:进程和线程