“线程是一个程序中不同的执行路径,而 进程是一个文件,是一个静态的概念。” —— 这是我在视频教程中看到的马士兵老师提出的通俗易懂且直击本质的观点。
![af624fe9b2180853eb46f7a9f3c363c2.png](https://i-blog.csdnimg.cn/blog_migrate/93b3a4ff67c75b2635c35070c613856c.jpeg)
Notes:
1. 哪种创建线程的方式更好
继承类 extends Thread 和实现接口 implements Runnable 都可以创建线程,不过我们应该尽量选择实现接口的方式,因为一个类可以实现多个接口,而 Java 只支持类的单继承。
2. Callable :call()
Callable接口中的 call() 方法的返回值是一个泛型,和Future、FutureTask 配合可以用来获取异步执行的结果。
3. 线程五态:创建、就绪、运行、阻塞和死亡
- 创建:生成线程对象;
- 就绪:start(),或者从等待或睡眠状态回来后;
- 运行:run()
- 阻塞:
- sleep():是 Thread 类的静态方法。线程进入休眠,但是对象的锁没有被释放,其他线程依然无法访问这个对象;
- wait():是Object类的方法。他可以释放锁,可以被 notify() 和 notifyAll() 方法唤醒;
- suspend():保持对锁的占有,直到其他线程调用resume()方法,因易造成死锁而弃用;
- 死亡:
- run():执行完毕,自然死亡;
- stop():杀死线程并释放所有锁,因过于残暴而弃用,容易造成数据的不同步。
4. 线程池中 submit() 和 execute() 的区别
- submit():返回值 Future 调用 get 方法时,可以捕获处理异常;
- execute():返回值是void,无法捕获异常。
![cd0aff67e3b66f19a90e5648ab0764c2.png](https://i-blog.csdnimg.cn/blog_migrate/2e5c87411141015f6ccdac19da386aba.png)
图:线程池的五态
5. 死锁的四个必要条件
- 互斥条件:某进程在使用完资源之前,不允许其他进程进行访问;
- 请求和保持条件:吃着碗里,看着锅里。进程获得一定的资源之后,继续请求其他资源;
- 不可剥夺条件:进程已获得的资源,在未完成使用之前不可被剥夺,只能在使用完后自己释放;
- 循环等待条件:是指进程发生死锁后,若干进程之间形成一种头尾相接的循环等待资源关系。
6. synchronized 和 volatile 的区别
首先,volatile 关键字是线程同步的轻量级实现,性能更好。它们还有如下区别:
- 目的不同:synchronized关键字解决多个线程之间访问资源的同步性,volatile解决变量在多个线程之间的可见性;
- 本质不同:synchronized 锁定当前对象,保证原子性,但 volatile 不保证原子性,它告诉 JVM 当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;
- 用法不同:volatile关键字只能用于变量,synchronized关键字可以修饰变量、方法和类;
- 性质不同:多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞;
- 优化不同:volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化。
7. synchronized 和 Lock 的区别
- 本质:synchronized是 Java 内置关键字,而 Lock是个 Java 类;
- 锁状态:synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
- 释放锁:synchronized 自动释放锁,Lock需在finally中调用unlock()方法释放锁;
- 适用范围:针对同步问题,Lock 锁适合大量代码,synchronized 锁适合少量代码。
8. Hibernate 的悲观锁和乐观锁的区别
- 悲观锁 认为在数据处理过程中极有可能存在修改数据的并发事务,于是将处理的数据设置为锁定状态。Hibernate中Session的get()和load()方法从数据库中加载对象时可以通过参数指定实现悲观锁。
- 乐观锁 认为对数据的并发操作不会经常性的发生,具有宽松的锁机制。通常通过数据版本标识来实现,读取数据时获得数据的版本号v,更新数据时v=v+1,此时v若大于数据库中此记录的当前版本号则更新数据,否则认为是过期数据无法更新。Hibernate中通过给实体类加整型的版本字段再通过XML或@Version注解进行配置实现乐观锁。它增加了一个版本字段,牺牲了系统的“空间”,提升了并发性,节省了“时间”,这便是 “「空间换时间」 思想。
本文部分整理参考互联网,此文仅用于个人总结无其他用途。