「这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战」。
1. 什么是线程?线程和进程的区别?
线程:系统分配处理器时间资源的基本单元。是程序执行的最小单位。
进程是操作系统资源分配的基本单位,线程是操作系统调度资源的基本单位。
进程是正在运行的程序的实例,其实就是系统中正在运行的一个应用程序, 线程是进程的一个实体。进程包含线程,线程共用进程的资源。
2. 描述CPU和多线程的关系
第一阶段,单CPU时代,单CPU在同一时间点,只能执行单一线程。
第二阶段,单CPU多任务阶段,计算机在同一时间点,并行执行多个线程。但这并非真正意义上的同时执行,而是多个任务共享一个CPU,操作系统协调CPU在某个时间点,执行某个线程,因为CPU在线程之间切换比较快,就好像多个任务在同时运行。
第三阶段,多CPU多任务阶段,真正实现的,在同一时间点运行多个线程。具体到哪个线程在哪个CPU执行,这就跟操作系统和CPU本身的设计有关了。
3. 什么是线程安全,线程不安全?
线程安全:就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。
线程不安全:就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据
4. ## 描述下线程的生命周期?
1、新建状态(New):新创建了一个线程对象。
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的 start()方法。该状态的线程位于“可运行线程池”中,变 得可运行,只等待获取 [CPU ]的使用权。即在就绪状态的进程除CPU 之外,其它的运行所需资源都已全部获得。
3、运行状态(Running):就绪状态的线程获取了 CPU,执行程序代码。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃 CPU 使用权,暂时停止运行。直到线程进入就绪状态,才有机会转 到运行状态。
阻塞的情况分三种:
(1)、等待阻塞:运行的线程执行 wait()方法,该线程会释放占用的所有资源,JVM 会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用 notify()或 notifyAll()方法才能被唤醒.
(2)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则 JVM 会把该线程放入“锁池”中。
(3)、其他阻塞:运行的线程执行 sleep()或 join()方法,或者发出了 I/O 请求时,JVM 会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者 I/O 处理完毕时,线程重新转入就绪状态。
5、死亡状态(Dead):线程执行完了或者因异常退出了 run()方法,该线程结束生命周期。
5.wait、sleep、join、yield的区别
1.wait:是 Object 类的方法,对此对象调用 wait 方法导致本线程放弃对象锁,进入等待锁定池,只有针对此对象发出 notify 方法(或 notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
2.sleep()方法 在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。不推荐使用。 sleep()使当前线程进入阻塞状态,在指定时间内不会执行。
3.yield方法 暂停当前正在执行的线程对象。 yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。 yield()只能使同优先级或更高优先级的线程有执行的机会。
4.join方法 一种特殊的wait,当前运行线程调用另一个线程的join方法,当前线程进入阻塞状态直到另一个线程运行结束等待该线程终止。 注意该方法也需要捕捉异常。
6.Synchronized和Lock的区别
主要相同点:Lock 能完成 synchronized 所实现的所有功能
主要不同点:Lock 有比 synchronized 更精确的线程语义和更好的性能。synchronized 会自动释放锁,而 Lock 一定要求程序员手工释放,并且必须在 finally 从句中释放。