zen cart 网站google plus,郑州七彩网站建设公司,家具公司网站建设,马鞍山网站建设报价文章目录 前言一、 线程与进程1.1 什么是线程与进程#xff1f;1.2 并发与并行1.3 同步调用与异步调用1.4 为什么要使用多线程#xff1f; 前言 在学习juc前#xff0c;需要先对进程和线程之间整体有一个认知。我们之前或多或少接触过#xff0c;一些特别高大上的概念… 文章目录 前言一、 线程与进程1.1 什么是线程与进程1.2 并发与并行1.3 同步调用与异步调用1.4 为什么要使用多线程 前言 在学习juc前需要先对进程和线程之间整体有一个认知。我们之前或多或少接触过一些特别高大上的概念比如多线程高并发 之类的。该文就是先对这些概念整体理清为后续学习扫清障碍。 一、 线程与进程
1.1 什么是线程与进程
进程 进程是用来存放数据与指令等运行程序的组成部分然后指令运行的时候还需用到磁盘、IO设备网络等其中进程就是用来加载指令管理内存·管理IO的。 程序运行的时候从磁盘 - 内存就代表一个进程开启了 进程可以看作一个程序的示例比如我们打开任务管理器 这表明对于应用来说可以运行一个或者多个进程。
线程
一个进程包括多个线程一个线程就是一个指令流将指令流的一条条指令以一定顺序交给CPU执行Java中线程是最小的调度单位进程作为资源分配的最小单位。windows中进程不活动只是作为线程的容器。
二者对比 :
进程拥有共享的资源比如内存空间的供子集线程共享进程间的通信较为复杂 同一台计算机的进程通信称为IPC比如套接字、消息队列等。不同计算机的通信要通过网路并遵守共同的协议比如http等。 线程通信比较简单因为它们可以共享进程内的内存一个例子是多个线程访问一个共享变量。线程更轻量级上下文切换成本较低。
1.2 并发与并行 并发两个及两个以上的任务在同一时间段执行并行两个及两个以上的任务在同一时刻执行 并发
在单核cpu中线程实际是串行执行的。操作系统中的组件叫做任务调度器将cpu的时间片windows下接近15ms分给不同的线程使用只是由于cpu在线程间的切换非常快导致体感上是同时运行的。
总结一句话微观串行宏观并行但是实际上还是串行。
并行
在多核cpu中每个核心可以处理一个线程这样就可以真正意义上实现并行即同一时刻同时运行多个线程。
如图 1.3 同步调用与异步调用
注意 代码中的Constants.MP4_FULL_PATH就理解为一个文件即可。
该代码作用就是花时间读取一个文件。
同步调用 异步调用 从运行结果可以看出来异步调用是通过一个Thread-0的线程执行的。
从上面的运行结果可以得到两者的含义。 同步调用发出一个调用之后结果没有返回的话该调用就不可以返回一直等待。
异步调用调用在发出后不用等待返回结果调用直接返回。 其实简单来说 异步调用就是在main线程里面新开一个线程并且新开的线程执行与否对于主线程接下来往下执行没有影响。 同步调用就是一直只执行当前线程呗不开其它的线程。
根据这个我们就可以引出下面的多线程
多线程的作用
多线程可以让方法执行变成异步的即不要干等着。比如读取磁盘文件时需要5秒那如果我们不使用多线程这5秒什么都做不了只能干等着。
1.4 为什么要使用多线程 在单核时代使用多线程可以提高cpu和io系统的运行效率如果只运行了一个java进程的情况下当线程进行读取io的操作此时线程被阻塞。如果没有多线程那么此时整个进程都被阻塞 无法使用cpu,系统整体效率只有50%。但是如果使用多线程的话一个线程阻塞其它线程还可以继续访问大大提高系统运行效率。但是需要理解的是单核中多线程并不起到减少时间的作用。单核只作了解 在多核时代。多线程主要是为了提高进程利用多核cpu的能力。
eg : 处理一个复杂的任务如果只有一个线程那么只有一个核心被利用到。失去了多核的作用但是多个线程就可以同时使用多个核心同时处理任务提高了解决任务的效率时间约等于单核时执行的时间 / cpu核心数。
实例
Benchmark
public int c() throws Exception {int[] array ARRAY;FutureTaskInteger t1 new FutureTask(()-{int sum 0;for(int i 0; i 250_000_00;i) {sum array[0i];}return sum;});FutureTaskInteger t2 new FutureTask(()-{int sum 0;for(int i 0; i 250_000_00;i) {sum array[250_000_00i];}return sum;});FutureTaskInteger t3 new FutureTask(()-{int sum 0;for(int i 0; i 250_000_00;i) {sum array[500_000_00i];}return sum;});FutureTaskInteger t4 new FutureTask(()-{int sum 0;for(int i 0; i 250_000_00;i) {sum array[750_000_00i];}return sum;});new Thread(t1).start();new Thread(t2).start();new Thread(t3).start();new Thread(t4).start();return t1.get() t2.get() t3.get() t4.get();
}
Benchmark
public int d() throws Exception {int[] array ARRAY;FutureTaskInteger t1 new FutureTask(()-{int sum 0;for(int i 0; i 1000_000_00;i) {sum array[0i];}return sum;});new Thread(t1).start();return t1.get();
}运行结果 上述代码含义就是
4个线程t1、t2、t3、t4每个线程调用方法执行2500万次打印信息中是c开头的。 d开头方法是一个方法调用1亿次。
c为异步调用d为同步调用从结果来看c方法的效率显著高于d方法Score越小效率越高。
但是如果是在单核cpu中的话不会出现性能的提升因为单核的本质上还是串行并不会产生并行的效果。