Java并发编程:进程和线程

.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 }
code { color: #FF0000 }
pre.src { background-color: #002b36; color: #839496 }

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

时间: 2024-08-03 20:30:28

Java并发编程:进程和线程的相关文章

Java并发编程--进程与线程

进程:百度百科说"进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.",维基百科说"是计算机中已运行程序的实体.进程本身不会运行,是线程的容器." 线程:百度百科说"线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元",维基百科说"是操作系统能够进行运算调度的最小单位.它被包涵在进程之中,是进程中的实际运作单位

【java并发编程实战】-----线程基本概念

学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习Java并发编程,共同进步,互相指导. 在学习Java并发之前我们需要先理解一些基本的概念:共享.可变.线程安全性.线程同步.原子性.可见性.有序性. 共享和可变 要编写线程安全的代码,其核心在于对共享的和可变的状态进行访问. "共享"就意味着变量可以被多个线程同时访问.我们知道系统中的资

Java并发编程系列(一)-线程的基本使用

最近在学习java并发编程基础.一切从简,以能理解概念为主. 并发编程肯定绕不过线程.这是最基础的. 那么就从在java中,如何使用线程开始. 继承Thread类 继承Thread类,重写run方法,new出对象,调用start方法. 在新启的线程里运行的就是重写的run方法. 1 /** 2 * 集成Thread类 实现run() 3 */ 4 public class C1 extends Thread { 5 6 @Override 7 public void run() { 8 try

Java并发编程(01):线程的创建方式,状态周期管理

本文源码:GitHub·点这里 || GitEE·点这里 一.并发编程简介 1.基础概念 程序 与计算机系统操作有关的计算机程序.规程.规则,以及可能有的文件.文档及数据. 进程 进程是计算机中的程序,关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在面向线程设计的计算机结构中,进程是线程的容器.程序是指令.数据及其组织形式的描述,进程是程序的实体. 线程 线程是操作系统能够进行运算调度的最小单

并发编程 --- 进程,线程

目录 进程 线程 进程 1.进程互斥锁 异步可以让多个任务在几个进程中并发处理,他们之间没有运行顺序,一旦开启也不受我们的控制,尽管并发编程让我们更加充分的利用IO资源,但是当多个进程使用同一份资源的时候,就会引发数据安全或顺序混乱的问题 import json import time from multiprocessing import Process from multiprocessing import Lock # 查看余票 def search(user): # 打开data文件查看

Java并发编程(02):线程核心机制,基础概念扩展

本文源码:GitHub·点这里 || GitEE·点这里 一.线程基本机制 1.概念描述 并发编程的特点是:可以将程序划分为多个分离且独立运行的任务,通过线程来驱动这些独立的任务执行,从而提升整体的效率.下面提供一个基础的演示案例. 2.应用案例 场景:假设有一个容器集合,需要拿出容器中的每个元素,进行加工处理,一般情况下直接遍历就好,如果数据偏大,可以根据线程数量对集合切割,每个线程处理一部分数据,这样处理时间就会减少很多. public class ExtendThread01 { publ

Java并发编程-如何终止线程

我们知道使用stop().suspend()等方法在终止与恢复线程有弊端,会造成线程不安全,那么问题来了,应该如何正确终止与恢复线程呢?这里可以使用两种方法: 1.使用interrupt()中断方法. 2.使用volatile boolean变量进行控制. 在使用interrupt方法之前,有必要介绍一下中断以及与interrupt相关的方法.中断可以理解为线程的一个标志位属性,表示一个运行中的线程是否被其他线程进行了中断操作.这里提到了其他线程,所以可以认为中断是线程之间进行通信的一种方式,简

Java并发编程学习:线程安全与锁优化

本文参考<深入理解java虚拟机第二版> 一.什么是线程安全? 这里我借<Java Concurrency In Practice>里面的话:当多个线程访问一个对象,如果不考虑这些线程在运行时环境下的调度和交替执行,也不需要额外的同步,或者调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象是线程安全的. 我的理解:多线程访问一个对象,任何情况下,都能保持正确行为,就是对象就是安全的. 我们可以将Java语言中各种操作共享的数据分为以下5类:不可变.

JAVA - 并发编程 - 执行器和线程池

思考? 1 为什么要使用执行器和线程池? 2 执行器和线程是什么?怎么使用 执行器 线程执行器分离了任务的创建和执行,提高了线程的性能 线程池 避免了频繁地创建和销毁线程,达到线程对象的重用,可以根据项目灵活地控制并发的数量 ExecutorService (java.util.concurrent) 1 Executors.newCachedThreadPool() 可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程 2 Executors.newFixedT

(并发编程)进程池线程池--提交任务的2种方式、协程--yield greenlet,gevent模块

一:进程池与线程池(同步,异步+回调函数)先造个池子,然后放任务为什么要用"池":池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务池子内什么时候装进程:并发的任务属于计算密集型池子内什么时候装线程:并发的任务属于IO密集型 #提交任务的两种方式:    # 同步调用:提交完一个任务之后,就在原地等待,等待任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行的    # 异步调用:提交完一个任务之后,不在原地等待,结果???,而是