freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Java并发系列教程之进程与线程解析
FreeBuf-357997 2023-04-17 15:33:13 120130
所属地 北京

进程

程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至CPU,数据加载至内存,在指令运行过程中还需要用到磁盘、网络等设备,进程就是用来加载指令、管理内存、管理IO等操作。

当一个程序被运行,从磁盘加载这个程序的代码至内存,这是就开启了一个进程。

进程就可以视为程序的一个实例,大部分程序可以同时运行多个实例进程(例如记事本等),也有的程序只能启动一个实例进程(例如网易云音乐等)。

线程

一个进程之内包含一到多个线程。

一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给CPU执行。

Java中,线程作为最小调度单位,进程作为资源分配的最小单位。

二者对比

进程基本上相互独立,而线程存在于进程中,是进程的一个子集。

进程拥有共享的资源,如内存空间等,供其内部的线程共享。

进程间通信较为复杂

1.同一台计算机的进程通信成为IPC(Inter-process communication)

2.不同计算机之间的进程通信,需要通过网络,并遵守共同的协议,例如HTTP

线程通信相对简单,因为他们共享进程的内存,例如多个线程可以访问同一个共享变量。

线程更轻量,线程上下文切换成本一般要比进程上下文切换低。

并行与并发

单核CPU下,多个线程实际还是串行执行,操作系统中有一个组件叫任务调度器,将CPU的时间片(windows下时间片最小约15毫秒)分给不同的程序使用,只是由于CPU在线程间(时间片很短)的切换非常快,人类感觉是同时运行的,总结为一句话就是:微观串行,宏观并行。

一般会将这种线程轮流使用CPU的做法成为并发(concurrent)。

CPU时间片1时间片2时间片3时间片4
core线程1线程2线程3线程4

表1

图1

多核CPU下,每个核(core)都可以调度运行线程,这时候线程可以是并行(parallel)。

CPU时间片1时间片2时间片3时间片4
core1线程1线程1线程3线程3
core2线程2线程4线程2线程4

表2

图2

引用Rob Pike的一段描述:

并发(concurrent)是同一时间应对(dealing with)多件事情的能力。

并行(parallel)是同一时间动手做(doing)多件事情的能力。

创建和运行线程

方法一、直接使用Thread

//创建线程对象 Thread thread = new Thread(){ @Override public void run() { //TODO doing 线程要执行的任务 } }; //启动线程 thread.start();

方法二、使用Runnable配合Thread

把【线程】和【任务】分开

Thread代表线程

Runnable可运行的任务(线程要执行的代码)

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        //TODO doing 线程要执行的任务
    }
};
//创建线程对象
Thread thread = new Thread(runnable);
//启动线程
thread.start();

方法三、FutureTask配合Thread

FutureTask能够接受Callable类型的参数,用来处理有返回结果的情况

FutureTask<Object> task = new FutureTask<>(new Callable<Object>() {
    @Override
    public Object call() throws Exception {
        //TODO doing 线程要执行的任务,并返回任务结束的结果
        return null;
    }
});
//创建线程对象
Thread thread = new Thread(task);
//启动线程
thread.start();
try {
    //当前线程会阻塞等待子线程任务task返回结果
    Object result = task.get();
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}

作者:刘跃明

# 系统安全 # 数据安全 # java # 并发安全 # JAVA安全
本文为 FreeBuf-357997 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
FreeBuf-357997 LV.6
专注技术的程序员一枚
  • 51 文章数
  • 3 关注者
网红直播带货你了解多少
2023-06-19
redis探秘:选择合适的数据结构,减少80%的内存占用,这些点你get到了吗?
2023-05-30
ElasticSearchRepository和ElasticSearchTemplate的使用
2023-05-26
文章目录