免责声明:

    本文内容多来自网络文章,转载为个人收藏,分享知识,如有侵权,请联系博主进行删除。

1.3、进程和线程

  • 线程和进程的概念、并行和并发的概念

线程和进程:
线程:是程序执行流的最小单元,是系统独立调度和分配CPU(独立运行)的基本单位。
进程:是资源分配的基本单位。一个进程包括多个线程。

区别:
1.线程与资源分配无关,它属于某一个进程,并与进程内的其他线程一起共享进程的资源。
2.每个进程都有自己一套独立的资源(数据),供其内的所有线程共享。
3.不论是大小,开销线程要更“轻量级”
4.一个进程内的线程通信比进程之间的通信更快速,有效。(因为共享变量)

多线程:同一时刻执行多个线程。用浏览器一边下载,一边听歌,一边看视频,一边看网页。。。
多进程:同时执行多个程序。如,同事运行YY,QQ,以及各种浏览器。

并发和并行:
并发:当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。
并行:当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。
强烈注意:多核,多cup,多机是不同的概念。

  • 创建线程的方式及实现

1、继承Thread类创建线程
2、实现Runnable接口创建线程
3、实现Callable接口通过FutureTask包装器来创建Thread线程
4、使用ExecutorService、Callable、Future实现有返回结果的线程
参考:Executor框架使用
Executor框架使用2

  • 进程间通信的方式

(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
(2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关 系 进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。
(3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送 信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
(4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺
(5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
(6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
(7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
(8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

而在java中我们实现多线程间通信则主要采用"共享变量"和"管道流"这两种方法

  • 说说 CountDownLatch、CyclicBarrier 原理和区别

  • 说说 Semaphore 原理

  • 说说 Exchanger 原理

  • ThreadLocal 原理分析,ThreadLocal为什么会出现OOM,出现的深层次原理

  • 讲讲线程池的实现原理

线程是稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池对线程进行统一分配、调优和监控,有以下好处:
1、降低资源消耗;
2、提高响应速度;
3、提高线程的可管理性。

Executors是java线程池的工厂类,通过它可以快速初始化一个符合业务需求的线程池。
newFiexedThreadPool
newCachedThreadPool
newSingleThreadExecutor
newScheduledThreadPool

当提交一个新任务到线程池时,线程池的处理流程如下。
1)线程池判断核心线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作
线程来执行任务。如果核心线程池里的线程都在执行任务,则进入下个流程。
2)线程池判断工作队列是否已经满。如果工作队列没有满,则将新提交的任务存储在这
个工作队列里。如果工作队列满了,则进入下个流程。
3)线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程
来执行任务。如果已经满了,则交给饱和策略来处理这个任务。

  • 线程池的几种实现方式

要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在Executors类里面提供了一些静态工厂,生成一些常用的线程池。

1.newCachedThreadPool:
底层:返回ThreadPoolExecutor实例,corePoolSize为0;maximumPoolSize为Integer.MAX_VALUE;keepAliveTime为60L;unit为TimeUnit.SECONDS;workQueue为SynchronousQueue(同步队列)
通俗:当有新任务到来,则插入到SynchronousQueue中,由于SynchronousQueue是同步队列,因此会在池中寻找可用线程来执行,若有可以线程则执行,若没有可用线程则创建一个线程来执行该任务;若池中线程空闲时间超过指定大小,则该线程会被销毁。
适用:执行很多短期异步的小程序或者负载较轻的服务器

2.newFixedThreadPool:
底层:返回ThreadPoolExecutor实例,接收参数为所设定线程数量nThread,corePoolSize为nThread,maximumPoolSize为nThread;keepAliveTime为0L(不限时);unit为:TimeUnit.MILLISECONDS;WorkQueue为:new LinkedBlockingQueue() 无界阻塞队列
通俗:创建可容纳固定数量线程的池子,每隔线程的存活时间是无限的,当池子满了就不在添加线程了;如果池中的所有线程均在繁忙状态,对于新任务会进入阻塞队列中(无界的阻塞队列),但是,在线程池空闲时,即线程池中没有可运行任务时,它不会释放工作线程,还会占用一定的系统资源。
适用:执行长期的任务,性能好很多

3.newSingleThreadExecutor:
底层:FinalizableDelegatedExecutorService包装的ThreadPoolExecutor实例,corePoolSize为1;maximumPoolSize为1;keepAliveTime为0L;unit为:TimeUnit.MILLISECONDS;workQueue为:new LinkedBlockingQueue() 无界阻塞队列
通俗:创建只有一个线程的线程池,且线程的存活时间是无限的;当该线程正繁忙时,对于新任务会进入阻塞队列中(无界的阻塞队列)
适用:一个任务一个任务执行的场景

4.NewScheduledThreadPool:
底层:创建ScheduledThreadPoolExecutor实例,corePoolSize为传递来的参数,maximumPoolSize为Integer.MAX_VALUE;keepAliveTime为0;unit为:TimeUnit.NANOSECONDS;workQueue为:new DelayedWorkQueue() 一个按超时时间升序排序的队列
通俗:创建一个固定大小的线程池,线程池内线程存活时间无限制,线程池可以支持定时及周期性任务执行,如果所有线程均处于繁忙状态,对于新任务会进入DelayedWorkQueue队列中,这是一种按照超时时间排序的队列结构
适用:周期性执行任务的场景

  • 线程的生命周期,状态是如何转移的

生命周期:
(1)新建状态——(2)就绪状态—((4)阻塞状态)—(3)运行状态——(5)死亡状态
详解:
(1)New:创建线程对象后,该线程处于新建状态,此时它不能运行,和其他Java对象一样,仅仅有Java虚拟机为其分配了内存,没有表现出任何线程的动态特征;
(2)Runnable:线程对象调用了start()方法后,该线程就进入了就绪状态(也称可运行状态)。处于就绪状态的线程位于可运行池中,此时它只是具备了运行的条件,能否获得CPU的使用权开始运行,还需要等待系统的调度;
(3)Runing:处于就绪状态的线程获得了CPU使用权,开始执行run()方法中的线程执行体,则线程处于运行状态。当一个线程启动后,它不能一直处于运行状态(除非它的线程执行体足够短,瞬间结束),当使用完系统分配的时间后,系统就会剥脱该线程占用的CPU资源,让其他线程获得执行的机会。只有处于就绪状态的线程才可能转换到运行状态。
(4)Blocked:一个正在执行的线程在某些特殊情况下,如执行耗时的输入/输出操作时,会放弃CPU的使用权,进入阻塞状态。线程进入阻塞状态后,就不能进入排队队列。只有当引用阻塞的原因,被消除后,线程才可以进入就绪状态。
——当线程试图获取某个对象的同步锁时,如果该锁被其他线程所持有,则当前线程进入阻塞状态,如果想从阻塞状态进入就绪状态必须得获取到其他线程所持有的锁。
——当线程调用了一个阻塞式的IO方法时,该线程就会进入阻塞状态,如果想进入就绪状态就必须要等到这个阻塞的IO方法返回。
——当线程调用了某个对象的wait()方法时,也会使线程进入阻塞状态,notify()方法唤醒。
——调用了Thread的sleep(long millis)。线程睡眠时间到了会自动进入阻塞状态。
——一个线程调用了另一个线程的join()方法时,当前线程进入阻塞状态。等新加入的线程运行结束后会结束阻塞状态,进入就绪状态。
线程从阻塞状态只能进入就绪状态,而不能直接进入运行状态,即结束阻塞的线程需要重新进入可运行池中,等待系统的调度。
(5)Terminated:线程的run()方法正常执行完毕或者线程抛出一个未捕获的异常(Exception)、错误(Error),线程就进入死亡状态。一旦进入死亡状态,线程将不再拥有运行的资格,也不能转换为其他状态。

  • 可参考

参考:Java多线程编程核心技术

java面试一、1.3线程与进程的更多相关文章

  1. Java进阶(四十四)线程与进程的特征及区别

    线程与进程的特征及区别 定义及特征 进程   指在系统中能独立运行并作为资源分配的基本单位,它是由一组机器指令.数据和堆栈等组成的,是一个能独立运行的活动实体. 进程的特征: 1.动态性:进程的实质是 ...

  2. [Other]面试复习笔记:线程与进程复习

    基本概念 1. 进程的基本概念 线程(thread)是进程(processes)中某个单一顺序的控制流,也被称为轻量进程(lightweight processes).进程是表示资源分配的基本单位,又 ...

  3. Python | 面试必问,线程与进程的区别,Python中如何创建多线程?

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题第20篇文章,我们来聊聊Python当中的多线程. 其实关于元类还有很多种用法,比如说如何在元类当中设置参数啦,以及一 ...

  4. Java面试中的“劲敌”线程,9个疑问全面解析

    作者:我是攻城师 (一)创建线程的方式 (1)实现Runnable接口 (2)继承Thread类 推荐使用接口,能够做到定义与实现分离,耦合更低 (二)关于线程的优先级 thread2.setPrio ...

  5. Java面试经典题:线程池专题

    1.什么是线程池 线程池的基本思想是一种对象池,在程序启动时就开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完成后线程对象归池, ...

  6. Java面试必问之线程池的创建使用、线程池的核心参数、线程池的底层工作原理

    一.前言 大家在面试过程中,必不可少的问题是线程池,小编也是在面试中被问啥傻了,JUC就了解的不多.加上做系统时,很少遇到,自己也是一知半解,最近看了尚硅谷阳哥的课,恍然大悟,特写此文章记录一下!如果 ...

  7. 【Java面试】Redis存在线程安全问题吗?为什么?

    一个工作了5年的粉丝私信我. 他说自己准备了半年时间,想如蚂蚁金服,结果第一面就挂了,非常难过. 问题是: "Redis存在线程安全问题吗?" 关于这个问题,看看普通人和高手的回答 ...

  8. java面试(进程和线程)04

    1.并行和并发有什么区别? 并行:多个处理器或多核处理器同时处理多个任务. 并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行. 2.线程和进程的区别 ...

  9. JAVA面试常见问题之进程和线程篇

    1.线程和进程的概念.并行和并发的概念 进程:计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本 ...

随机推荐

  1. js 获取get参数

    function get_val(url,key) { var two= url.split("?"); var right= two[1]; var values = right ...

  2. calico

    1. ipinip means what? 2. route 172.22.100.192/26 via 192.168.108.1 dev eth1 192.168.19.0/24 via 192. ...

  3. Tensorflow图像处理以及数据读取

    关于tensoflow的图像的处理,看到了一篇文章,个人觉得不错.https://blog.csdn.net/weiwei9363/article/details/79917942

  4. 一个简单的struts2上传图片的例子

    https://www.cnblogs.com/yeqrblog/p/4398914.html 在我的大创项目中有对应的应用

  5. Loadrunner进行HTTPS协议性能测试

    1.最简单办法就是在脚本前面加上:web_set_sockets_option("SSL_VERSION","TLS"),一般能解决HTTPS协议的请求问题,无 ...

  6. 爬取github项目。

    import requests from bs4 import BeautifulSoup url = 'https://github.com/login' headers = { 'User-Age ...

  7. HttpSession原理及Session冲突

    一.摘要         本文讨论了web服务器靠session id识别客户端.以及透过原理分析session冲突的原因,发现session冲突的原因是保存session id信息的cookie发生 ...

  8. cacti 流量图合并

    cacti 安装:https://www.cnblogs.com/weijie0717/p/4072711.html 一.需求介绍 由于交换机的多端口跑同一种流量,需要汇总统计.因此需要见多个端口的流 ...

  9. go语言语法基础

    1. go标记 Go 程序可以由多个标记组成,可以是关键字,标识符,常量,字符串,符号 如:fmt.Println("hello world") 2.行分隔符 在 Go 程序中,一 ...

  10. Bootstrap+PHP表单验证实例

    简单实用的Bootstrap+PHP表单验证实例,非常适合初学者及js不熟悉者,还有ajax远程验证 js验证表单 1 $(document).ready(function() { 2 $('#def ...