1、什么是线程?线程和进程的区别?
进程: 就是系统中运行的具有独立功能的程序,每运行一个程序就产生一个进程
线程: 线程是进程的一个分支,帮助进程完成某一项功能
区别:
基本单位: 进程是系统进行资源分配的基本单位,线程是CPU调度资源的基本单位
职责: 进程拥有自己独立的地址空间,而线程没有,它负责使用所属进程的地址空间共享数据
开销:
创建进程–>开销大,创建地址空间需要大量系统资源,
创建线程–>开销小,只有一个内核对象和一个堆栈,
切换进程–>开销大,
切换线程–>开销小,
进程通信–>开销大
线程通信–>开销小,
通信: 同一个进程下的线程通信十分方便,共享数据,而进程之间的通信需要通过管道,文件,套接字等完成
2、描述CPU和多线程的关系
CPU:
概念: 是一块超大规模的集成电路,是计算机的运算核心和控制核心
结构: 包括运算器,高速缓冲存储器,总线
工作: 解释计算机中的指令和处理计算机软件中的数据,对每一个应用进行统一协调和控制
关系:
线程的执行由cpu调度,
单cpu单线程:一个cpu控制一个线程执行
单cpu多线程: 一个cpu控制多个线程执行,同一时间只能执行一个线程,其他的会暂停
多cpu多线程: 同一时间,多个cpu同一时间执行多线程
3、什么是线程安全/线程不安全?
-
线程安全:
- 多个线程访问同一个资源,采用线程同步机制,使每个线程的操作结果和单线程下的操作结果一致
-
线程不安全:
- 未使用加锁机制,在多个线程操作同一个数据,先后更改得到的数据不准确,
-
扩展: 引起线程安全问题的原因:
- 主要是由全局变量和静态变量引起的
如果多线程只对全局变量和静态变量做读操作是不会出现线程安全问题的,但是当有多个线程同时执行写操作,这时会出现线程安全问题,此时我们就需要考虑线程同步的问题了
4、描述下线程的生命周期?(画图)
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AT4gUspr-1608190923180)(C:\Users\admin\Desktop/线程生命周期.jpg)]
5、wait、sleep、join、yield的区别
wait: 让出cpu资源和锁资源,当前线程被放入对象等待池中,只有调用notify()方法才能从对象等待池中随机唤醒一个等待的线程,使其进入就绪状态,notifyAll()将所有对象等待池中的线程都唤醒(wait用于锁机制)
sleep: 让出cpu资源,但是不会释放锁, 睡眠结束进入就绪状态等待下一次分配时间片继续执行,也可调用interrupt()方法唤醒
sleep和wait的区别
sleep是线程方法,wait是object方法
主要区别: sleep让出cpu资源,不释放锁资源,而wait都释放
yield: 让出cpu资源和锁资源,直接进入就绪状态,(可能马上又被选中执行),而且只能让同优先级的线程有执行的机会
join: 当一个线程调用另一个线程的join方法,这个线程进入阻塞状态知道加入的线程执行结束后,此线程才会进入就绪状态获取下次cpu资源才会执行,
6、Synchronized和Lock的区别
synchronized:
安 全 性 : 是java内置的关键字,给资源加锁,每次只有一个线程可以操作资源,其他线程会阻塞,保证了线程的绝对安全,
存在问题: 如果持有锁的线程被阻塞,又没有释放锁,其他线程只能等待,十分影响程序的执行效率
释放锁的情况:
一种是: 执行完该代码,会自动释放锁
一种是: 线程发生异常,JVM会让该线程释放锁
Lock: 因为sychronized存在阻塞的问题,java5引入了lock
安全性: 是一个类,不是java内置的,可以使线程之间实现同步访问,保证线程安全,
与sychronized相比: ReadWriteLock锁,含有一对读写相关的锁,读操作可以多个线程同时保持,而写锁时独有的,只能有一个线程持有,避免了线程之间读写,写写的冲突,
7、ThreadLocal、Volatile、Synchronized 的作用和区别
1.volatile:
作用:volatile主要是用来在多线程中同步变量。
区别:而当一个变量被volatile修饰后,该变量就不能被缓存到线程的内存中
2、ThreadLocal:
作用:它只是一个线程的局部变量(其实就是一个Map),ThreadLocal会为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
区别:Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离
3.synchronized:
作用:synchronized关键字是Java利用锁的机制自动实现的,一般有同步方法和同步代码块两种使用方式
区别:1、volatile不需要同步操作,所以效率更高,不会阻塞线程,但是适用情况比较窄
2、volatile读变量相当于加锁(即进入synchronized代码块),而写变量相当于解锁(退出 synchronized代码块)
3、synchronized既能保证共享变量可见性,也可以保证锁内操作的原子性;volatile只能保证可见性
8、同步方法和同步块,哪个更好?
同步块是更好的选择,因为它不会锁住整个对象。同步方法会锁住整个对象
同步块更要符合开放调用的原则,只在需要锁住的代码块锁住相应的对象,这样
从侧面来说也可以避免死锁。
9、什么是死锁?如何避免死锁?
所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,此时称系统处于死锁状态或系统产生了死锁。
避免死锁:
1、避免多次锁定。尽量避免同一个线程对多个 Lock 进行锁定
2、具有相同的加锁顺序。如果多个线程需要对多个 Lock 进行锁定,则应该保证它们以相同的顺序请求加锁
3、使用定时锁。
4、死锁检测。死锁检测是一种依靠算法机制来实现的死锁预防机制,它主要是针对那些不可能实现按序加锁,也不能使用定时锁的场景的
10、常见的线程池叫什么,线程池的作用是什么
1.newCachedThreadPool创建一个可缓存线程池
作用:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
2.newFixedThreadPool 创建一个定长线程池
作用:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3.newScheduledThreadPool 创建一个定长线程池
作用:创建一个定长线程池,支持定时及周期性任务执行。
4.newSingleThreadExecutor 创建一个单线程化的线程池
作用:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
缺点:多余的连接池会造成资源浪费
应用场景:
:创建一个定长线程池,支持定时及周期性任务执行。
4.newSingleThreadExecutor 创建一个单线程化的线程池
作用:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
缺点:多余的连接池会造成资源浪费
应用场景:
数据库连接池原理: