走近并发编程之一 进程和线程

并发与并行,进程与线程不仅是操作系统中及其重要的概念,也是并发编程入门

必须要理解的核心知识。

  1. 什么是并发?并发与并行的区别

顺序编程:程序中的所有事物在任意时刻都只能执行一个步骤

并发:在同一时间段内,需要处理多个任务,而在每个时间点又只能处理一个,这就是并发。

假设我们要把多个任务分配给处理机,如果这台机器有多个处理器,显然可以同时执行这些任务,这就是并行

不同于并行,并发的目的旨在最大限度的提高程序在单处理器上的效率。前者是在物理上的同时发生,而并发是在逻辑上的同时发生。如图,如果要在同一个时间段内处理task1, task2,需要在任务之间来回切换,完成并发执行

图:一个简单并发的例子

2.  Java的多线程和并发性

Java是一种多线程语言,并发是Java非常重要的高级特性之一。对于分布式系统甚至于web系统的开发者来说,学会高效的并发编程至关重要。例如,web系统是Java的常见应用之一,最基本的java web库类 Servlet就具备天生的多线程特性,图形用户界面类似于Swing和SWT也具备线程安全的机制。如果你不了解并发,你很难很好的使用好这些工具。

3.  进程和线程

进程可以定义为一个执行中的程序的实例,进程拥有自己的地址空间,以及用来记录进程的进程控制块(PCB)。想到实现并发,人们最先想到的便是通过进程。在多任务操作系统中,CPU会周期性地从一个进程切换到另一个进程。这种实现方式非常理想化,由于不同进程处于不同的地址空间,彼此之间不会干涉,这使得实现起来更为容易。

可惜的是,虽然具有以上优点,但由于进程通常都会有开销和数量的限制,想要使用进程来并发编程显然不够经济。

图:进程的开销( 任务管理器)

函数型语言可以将并发任务彼此隔离,这种专门的并发语言为处理大量并发任务提供了方便。

线程是在单一进程中创建的任务,线程与线程之间共享进程的地址空间和内存资源,Java的并发就是在顺序语言的基础上引入线程机制,通过多线程 之间的协作来实现并发。

多线程并发的好处是可以共享资源,开销较小,然而同时也使得系统的复杂性增加。不过与程序设计的方便性,资源的负载均衡实现相比,复杂性代价也变得微不足道了。

4.  线程的创建

Java中创建线程,经常用到java.lang.Thread类,如下创建一个线程:

Thread thread  = new Thread();

调用start()方法启动线程

thread.start();

由于我们没有继承Thread类,重载Thread的run()方法,所以在start()之后线程没有任何动作。

要想让线程执行我们想要它完成的任务,还需要创建Thread的子类来重载run()方法。

5.  创建Thread子类

举个栗子

public class MyThread extends Thread {

    public void run(){

        System.out.println("ACFLOOD!");

    }

}

通过如下代码来运行MyThread

MyThread myThread = new MyThread();

myThread.start();

6.  实现Runnable接口

我们还可以通过实现Runnable接口来实现run()方法,你可能会问,Runnable和Thread的区别是什么? 其实,在Java的多线程机制中,Runnable的实现就相当于一个Task,也就是我们想让线程完成的任务。Thread的目的是用来驱动这些任务,我们想要执行Task,只需要把Runnable的实例放入Thread中。比如下面的倒计时任务LiftOff

public class LiftOff implements Runnable {

  protected int countDown = 10; //Default

  private static int taskCount = 0;

  private final int id = taskCount++;

  public LiftOff(){}

  public LiftOff(int countDown){

      this.countDown = countDown;

  }

  public String status() {

      return "#" + id  + "(" + (countDown > 0 ? countDown : "LiftOff!")+").";

  }

  public void run(){

      while(countDown-- > 0){

        System.out.print(status());

        Thread.yield(); //对线程调度的建议

    }

  }

}

我们可以直接调用run()方法来执行

public class MainThread {

    public static void main(String[] args){

        LiftOff launch = new LiftOff();

        laucn.run();

    }

}

更好的办法是交给Thread类来调度

public class BasicThreads{

     Thread t = new Thread(new LiftOff());

     t.start();

     System.out.println("Waiting for LiftOff");       

}

在这个例子中,start()方法执行之后返回,之后输出main()主线程中的waiting for liftoff,run()在另一个线程最后执行完成。

7.  总结

通过本文的学习,相信读者对并发的基本概念,并发基本的实现原理,以及java多线程对于线程的创建有了初步的了解。在本系列的后续部分将会继续探讨并发编程中的细节。

如果觉得本文对您有所帮助的话,就给俺点个赞吧~

时间: 2024-12-30 13:29:20

走近并发编程之一 进程和线程的相关文章

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

并发编程之进程与线程

并发编程之进程与线程 2.1 线程与进程 2.1.1 进程 2.1.2 线程 2.1.3 二者对比 2.2 并行与并发 2.3 应用 2.1 线程与进程 2.1.1 进程 程序指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至CPU,数据加载至内存.在指令运行过程中还需要用到磁盘.网络等设备.进程就是用来加载指令.管理内存.管理IO的. 当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程. 进程就可以视为程序的一个实例.大部分程序可以同时运行多个实例进程(例如记

9)网络并发 编程、进程、线程和协程

并发网络 Server: #!/usr/bin/env python#-*-conding:utf-8-*-import socketsk = socket.socket()sk.bind(('127.0.0.1',9009))sk.listen()conn,addr = sk.accept()conn.send(b'heooo')msg = conn.recv(1024)print(msg)conn.close()sk.close() Client: #!/usr/bin/env python

(转)iOS 各种网络编程总结--进程、线程、Socket、HTTP、TCP/IP、TCP和UDP

######################################################### 进程与线程 进程和线程都是由操作系统分配和调度的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性. 进程是一块包含了某些资源的内存区域.操作系统利用进程把它的工作划分为一些功能单元.进程中所包含的一个或多个执行单元称为线程(thread).进程还拥有一个私有的虚拟地址空间,该空间仅能被它所包含的线程访问. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更

Python3 异步编程之进程与线程-1

Python3 异步编程之进程与线程-1 一.了解进程间通信 进程间通信 进程 线程 线程 vs 进程 IO模型 并发 vs 并行 异步 vs 同步 二.多线程与多进程的用法 计算密集型 vs I/O密集型 GIL 多线程 多进程 三.协程的好处与用法 协程 yield yield from 四.进程间通信-IPC 01 管道:无名管道和命名管道(FIFO) 消息队列 信号量 共享存储 Socket Streams 相关定义: 管道: 命名管道: 消息队列: 信号量: 共享内存: 元子操作: 五

【转】Java并发编程:如何创建线程?

一.Java中关于应用程序和进程相关的概念 在Java中,一个应用程序对应着一个JVM实例(也有地方称为JVM进程),一般来说名字默认是java.exe或者javaw.exe(windows下可以通过任务管理器查看).Java采用的是单线程编程模型,即在我们自己的程序中如果没有主动创建线程的话,只会创建一个线程,通常称为主线程.但是要注意,虽然只有一个线程来执行任务,不代表JVM中只有一个线程,JVM实例在创建的时候,同时会创建很多其它的线程(比如垃圾收集器线程). 由于Java采用的是单线程编

Java并发编程 - 逐级深入 看线程的中断

最近有足够的空闲时间 去东看看西看看,突然留意到在Java的并发编程中,有关线程中断的,以前初学时一直没弄清楚的一些小东西. 于是,刚好把收获简单的总结一下,通过此文来总结记录下来. 从源码看线程的状态 在开始分析线程的中断工作之前,我们肯定要先留意一个点,那就是肯定是有开启,才会有与之对应的中断工作出现. 开启一个线程的工作,相信每个Javaer都烂熟于心.它很简单,new一个thread对象,然后调用start方法开启线程. 那么,一个好玩的问题就出现了:既然开启一个线程的步骤如此简单明了,

并发技术、进程、线程和锁拾遗

并发技术.进程.线程和锁拾遗 Part1. 多任务 计算机发展起初,CPU 资源十分昂贵,如果让 CPU 只能运行一个程序那么当 CPU 空闲下来(例如等待 I/O 时),CPU 资源就会被浪费,为了使 CPU 资源得到更好的利用,先驱编写了一个监控程序,如果发现某个程序暂时无需使用 CPU 时,监控程序就把另外的正在等待 CPU 资源的程序启动起来,以充分利用 CPU资源.这种方法称为 - 多道程序(Multiprogramming) 对于多道程序,最大的弊端是各程序之间不区分轻重缓急,对于用

Python并发编程之进程2

引言 本篇介绍Python并发编程下的进程,先介绍进程的相关知识,然后对python中multiprocessing模块进行介绍(Process.Pipe.Queue以及 Lock). 进程(process) 在面向线程设计的系统(如当代多数操作系统.Linux 2.6及更新的版本)中,进程本身不是基本运行单位,而是线程的容器. 进程拥有自己独立的内存空间,所属线程可以访问进程的空间. 程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 例如,我们在PyCharm开发环境中写