线程八股文--藤原豆腐店自用
目录
1.什么是进程、什么是线程,他们之间是什么关系?
1.1.进程是什么?
1.2.线程是什么?
1.什么是进程、什么是线程,他们之间是什么关系?
1.1.进程是什么?
是具有一定独立功能的程序,他是系统进行资源(内存)分配和调度的最小单位
进程是可以独自运行的一段程序
1.2.线程是什么?
线程是进程的一个实体,是CPU调度和分派的基本单位
他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源
1.3.两者之间的关系
- 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程(主线程)
- 资源分配给进程,同一进程的所有线程共享该进程的所有资源
- 线程在执行的过程中,需要协作同步。不同的进程的线程间需要利用消息通信的办法实现同步
- CPU是分给线程,即真正在CPU上运行的是线程
- 、线程是指进程内的一个执行单元,也就是进程内的可调度实体
2.Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?
创建一个线程有4种方式:
- 继承Thread类 继承的扩展性不强,java只支持单继承,如果一个类继承Thread类就不能继承其他类了
- 实现Runnable接口
- 实现Callable接口,重写call方法(有返回值)
- 通过线程池
如何区分线程?
在一个系统中有很多线程,每个线程都会打印日志,我想区分是哪个线程打印的怎么办?
thread.setName(“设置一个线程名称”); 这是一种规范,在创建线程完成后,都需要设置名称。
可以使用synchronized关键字修饰同步方法
3.Callable与Runnable区别:
Callable | Runnable | |
返回值 | 执行结果 | 无 |
异常 | 抛出异常 | 不可,必须在内部解决 |
方法 | call()方法 | run()方法 |
效率 | 高 | 低 |
4.守护线程是什么?用什么方法守护线程?
守护线程是运行在后台的一种特殊进程。
它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件
在Java中垃圾回收线程就是特殊的守护线程
5.什么是串行、并发、并行?
串行的特点:前一个任务没搞定,下一个任务就只能等着。
并行是指程序在某一时刻处理事件的能力
并行的关键是你有同时处理多个任务的能力,最关键的点就是:是否是『同时』。
并发是指程程序在某一时间段处理事件的能力
并发的关键是你有处理多个任务的能力,不一定要同时
6.启动一个线程是用run方法还是start方法?
启动一个线程是调用start方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可由JVM调度并执行。
但是这并不意味着线程会马上执行,而启动以后执行的方法是run方法
7.sleep方法和wait方法的区别和共同点
共同点:两者都可以暂停线程的执行
不同点:
sleep方法没有释放锁,wait方法释放了锁
sleep方法用于暂停执行,wait方法用于线程之间的交互通信
sleep方法调用后,执行完毕线程会自动苏醒
wait方法被调用后,线程不会自动苏醒需要别的线程调用同一个对象上的notify方法或者notifyAll方法,或者可以使用wait(long timeout)超时后线程会自动苏醒。
8.线程状态
线程从执行状态出来后都不能直接回到执行状态,而是要回到待执行状态
1. 新建( new ):新创建了一个线程对象。
2. 可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 start ()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取 cpu 的使用权 。
3. 运行( running ):可运行状态( runnable )的线程获得了 cpu 时间片( timeslice ) ,执行程序代码。
4. 阻塞( block ):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cpu timeslice ,暂时停止运行。直到线程进入可运行( runnable )状态,才有 机会再次获得 cpu timeslice 转到运行( running )状态。阻塞的情况分三种:
Blocked(堵塞)状态:
同步锁;调用了sleep()和join()方法进入Sleeping状态;执行wait()方法进入Waiting状态,等待其他线程notify通知唤醒);
(一). 等待阻塞:运行( running )的线程执行 o . wait ()方法,JVM 会把该线程放入等待队列( waitting queue )中。
(二). 同步阻塞:运行( running )的线程在获取对象的同步锁时(synchronized),若该同步锁被别的线程占用,则 JVM 会把该线程放入锁池( lock pool )中。
(三). 其他阻塞: 运行( running )的线程执行 Thread . sleep ( long ms )或 t . join ()方法,或者发出了 I / O 请求时, JVM 会把该线程置为阻塞状态。当 sleep ()状态超时、 join ()等待线程终止或者超时、或者 I / O 处理完毕时,线程重新转入可运行( runnable )状态。
5. 死亡( dead ):线程 run ()、 main () 方法执行结束,或者因异常退出了 run ()方法,则该线程结束生命周期。死亡的线程不可再次复生。
9.线程池的作用
限定线程的个数,不会导致由于线程过多导致系统运行缓慢或者崩溃
线程池不需要每次都去创建和销毁,,节约了资源
线程池不需要每次都去创建,响应速度更快
注:数据库线程池一样
10.线程池常用类
Java里面线程池的顶级接口是Executor,不过真正的线程池接口是ExecutorService,
ExecutorService的默认实现是ThreadPoolExecutor
普通类Executors里面调用的就是ThreadPoolExecutor,Executor是线程创建工厂类
10.1.Executors提供了四种线程池:
1)newCachedThreadPool 线程池根据需求创建线程,可扩容,遇强则强(银行一共10个窗口,只开放了3个窗口,其他7个窗口没有开放,如果人很多就要开放其余的窗口,高峰结束再回复到3个窗口状态)
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.
特点:
1、线程池中数量没有固定,可达到最大值(Interger. MAX_VALUE)
2、线程池中的线程可进行缓存重复利用和回收(回收默认时间为 1 分钟)
3、当线程池中,没有可用线程,会重新创建一个线程
场景: 适用于创建一个可无限扩大的线程池,服务器负载压力较轻,执行时间较短,任务多的场景
2)newSingleThreadExecutor 一个任务一个任务执行,一池一线程(例如窗口只能服务一个人,后面来的只能等待)
创建是一个单线程池,也就是该线程池只有一个线程在工作,所有的任务是串行执行的,如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它,
此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
特点: 线程池中最多执行 1 个线程,之后提交的线程活动将会排在队列中以此执行
场景: 适用于需要保证顺序执行各个任务,并且在任意时间点,不会同时有多个线程的场景
3)newFixedThreadPool (int) 一池N线程
创建固定大小的线程池,每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小,线程池的大小一旦达到最大值就会保持不变。
特征:
1、线程池中的线程处于一定的量,可以很好的控制线程的并发量
2、线程可以重复被使用,在显示关闭之前,都将一直存在
3、超出一定量的线程被提交时候需在队列中等待
场景: 适用于可以预测线程数量的业务中,或者服务器负载较重,对线程数有严格限制的场景
4)newScheduledThreadPool (了解)
创建一个大小无限的线程池,此线程池支持定时以及周期性执行任务的需求。
场景: 适用于需要多个后台线程执行周期任务的场景
11.创建线程池的核心参数
都是通过new ThreadPoolExecutor来构造线程池,线程池相关参数的概念:
1)corePoolSize:3 线程池的核心线程数(常驻线程数)
线程池的核心线程数(常驻线程数),一般情况下不管有没有任务都会一直在线程池中一直存活
2)maximumPoolSize: 7 线程池所能容纳的最大线程数
线程池所能容纳的最大线程数,当活动的线程数达到这个值后,后续的新任务将会被阻塞。
3)keepAliveTime:4 线程闲置时的超时时长
控制线程闲置时的超时时长,超过则终止该线程。一般情况下用于非核心线程
4)unit: 时间单位
用于指定 keepAliveTime 参数的时间单位,TimeUnit 是个 enum 枚举类型,常用的有:TimeUnit.HOURS(小时)、TimeUnit.MINUTES(分钟)、TimeUnit.SECONDS(秒) 和 TimeUnit.MILLISECONDS(毫秒)等。
5)workQueue:任务队列(阻塞队列)
当核心线程数达到最大时,新任务会放在队列中排队等待执行。
6)threadFactory:线程工厂
线程工厂,它是一个接口,用来为线程池创建新线程的。
7)RejectedExecutionHandler handler: 拒绝策略(银行有10个窗口,核心是3个窗口,所有窗口都开放,等待的座位也坐满了,银行再来新的顾客,银行没有能力接受新的顾客,银行就要做一个拒绝策略,建议去别的银行)
12. 线程池工作流程
1、在创建了线程池后,线程池中的线程数为零
2、当调用 execute()方法添加一个请求任务时,线程池会做出如下判断:
2.1 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;
2.2 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列;
2.3 如果这个时候队列满了且正在运行的线程数量还小于maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;
2.4 如果队列满了且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会启动饱和拒绝策略来执行。当提交的任务数大于(workQueue.size() +maximumPoolSize ),就会触发线程池的拒绝策略。
3、当一个线程完成任务时,它会从队列中取下一个任务来执行
4、当一个线程无事可做超过一定的时间(keepAliveTime)时,线程会判断:
4.1 如果当前运行的线程数大于 corePoolSize,那么这个线程就被停掉。
4.2 所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。
13.自定义线程池
在实际项目开发中,推荐手动创建线程池
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式
这样的处理方式让写的人能够更加明确线程池的运行规则,避免资源耗尽的风险
//自定义线程池创建
public class ThreadPoolDemo2 {public static void main(String[] args) {ExecutorService threadPool = new ThreadPoolExecutor(2,5,2L,TimeUnit.SECONDS,new ArrayBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());//10个顾客请求try {for (int i = 1; i <=10; i++) {final int index = i;//执行threadPool.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+" 为第"+index+"个客户办理业务");}});}}catch (Exception e) {e.printStackTrace();}finally {//关闭threadPool.shutdown();}}
}
14.synchronized和lock锁的区别
- synchronized内置的Java关键字 ,Lock是一个Java类
- synchronized无法判断获取锁的状态,Lock可以判断是否获得了锁
- synchronized会自动释放锁,Lock必须要手动释放锁,如果不释放锁会产生死锁
- synchronized线程1获得锁,线程2等待,Lock锁就不一定会一直等待下去,Lock.tryLock()可以尝试去获取锁,不会一直去等待,等不到就结束
- synchronized可重入锁,不可以中断的,非公平的;Lock锁可重入的,可以判断锁,非公平的
- synchronized适合锁少量的代码同步问题,Lock适合锁大量的同步代码
Lock的使用
// 1、创建锁
private Lock lock = new ReentrantLock();
// 2、加锁
lock.lock();
try {// 3、access the resource protected by the lock// 业务代码
} finally {// 4、解锁lock.unlock();
}
15.Volatile
Volatile是Java虚拟机提供的轻量级同步机制
1 保证可见性
可见性就是当一个线程 修改一个共享变量时,另外一个线程能读到这个修改的值
2 不保证原子性
原子性就是不可分割的,线程执行任务的时候,是不可分割的,要不同时成功,要不同时失败
3 禁止指令重排
指令重排是指在程序执行过程中,为了提高性能, 编译器和CPU可能会对指令进行重新排序
线程八股文--藤原豆腐店自用相关推荐
- Java八股文--藤原豆腐店自用
目录 1.Java跨平台的原理 2.基本数据类型所占字节数 3.Java中表示价格为啥不用double,而是用BigDecimal 4.双精度&单精度的区别 5.面向对象的特征 5.1.封装: ...
- 数据库八股文--藤原豆腐店自用
目录 数据库的分类和常见的数据库你知道那些? 关系型数据库 非关系型数据库 介绍一下三范式,设计表时一定要追求三范式吗? 数据库的分类和常见的数据库你知道那些? 关系型数据库 典型产品:MySQL.S ...
- Java反射--藤原豆腐店自用
什么是反射? JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为j ...
- JVM--藤原豆腐店自用
目录 1.类加载 1.1.JVM类加载过程: 1.2.类的初始化过程 1.3.类加载器 1.3.1.启动类加载器(BootStrap ClassLoader) 1.3.2.扩展类加载器(Extensi ...
- JDBC--藤原豆腐店自用
Java Database Connectivity,简称JDBC 是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法. 驱动程序 驱动程序:数据 ...
- 龙族幻想最新东京机器人位置_龙族幻想藤原智坐标位置一览 藤原智任务攻略...
龙族幻想v1.3.148安卓版 类型:角色扮演大小:1.39G语言:中文 评分:5.0 标签: 立即下载 龙族幻想藤原智在哪?这是苍穹之下异闻,需要找到npc藤原智,许多玩家都不清楚在什么位置,如何完 ...
- The annotation of C++ primer {藤原豆腐坊自家用}
The annotation of <<C++ primer>> {藤原豆腐坊自家用} 给变量名一个初始值几乎总是正确的. 但不要求必须这么做 C++的主要设计目的之一就是允许 ...
- [画风突变] 藤原千花专属相册,C语言制作书记专属电子相册!
前言 一款自己制作的电子相册不仅富有创意,而且能够最大可能的满足己需,今天小编带着大家制作的就是藤原千花的电子相册.要是你愿意,你也可以把你和你对象的点滴放进去哦,弄点爱情宣言什么的都是没什么问题. ...
- 《如何有效阅读》藤原和博 读书笔记
感想 1.整本书内容零散: 主旨是如何有效阅读,但是阅读方法不成系统,更像是零散的想法,或者说是作者想到什么就写什么.第一遍读完以后,大脑里没有什么整体思路,觉得作者说的有道理,但是没有实质性的方法建 ...
最新文章
- html false插件,解析webpack插件html-webpack-plugin
- 拜托,面试别再问我JVM了!!!
- 推荐8个冷门但硬核的软件和网站,你一定不能错过!
- 我的fedora10的virtual box网络设置
- 【OO学习】OO第四单元作业总结及OO课程总结
- VC++ 访问数据库实例详解图解
- Silverlight for Windows Phone 7开发体验
- wxWidgets:wxWindow类用法
- wxWidgets:wxDirPickerCtrl类用法
- Interleaving String
- 关于SQLContext过期,SparkSession登场
- css没有border,你未必知道的CSS小知识:为什么没有人使用border-image
- 程序员求职之道(《程序员面试笔试宝典》)之民间的企业排名的可信度到底有多大?...
- Safari 搜寻引擎被 Yahoo 绑架,试试这 4 种解决方法
- 小学英语口语测试软件,最新小学英语口语测试题(四年级)
- 包邮送5本!新书推荐:MLOps实践――机器学习从开发到生产
- 机器学习-入门杂谈(转载)
- phyton题库+解析
- bixby服务器没响应,猫盘开启ssh教程(原版系统,听闻一键x3p已经不能用了!)...
- 华中科技大学计算机系统基础实验3报告,华中科技大学计算机系统基础实验报告...
热门文章
- 过压电路保护元器件详解,一文就看明白了
- 微信产品经理-张小龙:如何把产品做简单
- [Solved] Can not extract resource from com.android.aaptcompiler
- 帮助新员工快速形成战斗力,Filez在入职与培训场景应用
- java向量加法_结构-03. 平面向量加法(10) java
- win产品密钥大搜集
- win8dnf计算机内存不足,Win8电脑内存不足解决方法介绍
- 在Ubuntu中安装Chrome浏览器
- Linux系统配置(磁盘管理)
- Linux环境下java安装、配置