文章目录
一、进程与线程认知强化
1.1如何理解进程与线程?
1.2如何理解多线程中的并发与并行?
1.3如何理解线程的生命周期及状态变化?
二、线程并发安全问题认知强化
2.1如何理解线程安全与不安全?
2.2导致线程不安全的因素有哪些?
2.3.如何保证并发线程的安全性?
2.4Synchronized关键字应用及原理分析?
2.5如何理解volatile关键字的应用?
2.6如何理解happen-before原则应用?
2.7如何理解JAVA中的悲观锁和乐观锁?
2.8如何理解线程的上下文切换?
2.9如何理解死锁以及避免死锁问题?
三、线程通讯与进程通讯应用基础
3.1如何理解进程与线程通讯?
3.2如何实现进程内部线程之间的通讯?
3.2.1基于wait/nofity/notifyall实现
3.2.2基于Condition实现
3.3如何实现进程之间间通讯(IPC)?
3.3.1基于socket实现进程间通讯?
进程:操作系统进行资源调度和分配的基本单位(例如浏览器,APP,JVM);
线程:进程中的最小执行单位,是CPU资源的分配的基本单位(可以理解为一个顺序的执行流);
说明:多个线程可以共享所属进程的所有资源。
Java从入门到项目实战java语言编程入门书零基础自学教程淘宝¥49.8¥79.8购买已下架并发:多线程抢占CPU,可能不同时执行,侧重于多个任务交替执行。
现在的操作系统无论是windows,linux还是macOS等其实都是多用户多任务分时操作系统,使用这些操作系统的的用户可以“同时”干多件事情。但实际上,对于单机CPU的计算机而言,在同一时间只能干一件事,为了看起来像是“同时干多件事”分时操作系统把CPU的时间划分成了长短基本相同的时间区间,即“时间片”,通过操作系统的管理,把时间片依次轮流的分配给各个线程任务使用。我们看似的“同时干多件事”,其实是通过CPU时间片技术并发完成的。
并行:线程可以不共享CPU,可每个线程一个CPU同时执行多个任务。
总之:个人认为并行只出现在多CPU或多核CPU中,而并发可理解为并行中的一个子集。
一个线程从创建,运行,到最后销毁的这个过程称之为线程的生命周期,在这个生命周期过程中线程可能会经历如下几个状态:
这些状态可归纳为:新建状态,就绪状态,运行状态,阻塞状态,死亡状态;
多个线程并发执行时,仍旧能够保证数据的正确性,这种现象称之为线程安全;
多个线程并发执行时,不能能够保证数据的正确性,这种现象称之为线程不安全。
案例1:模拟多个线程同时执行售票操作
Java核心技术卷I基础知识(原书第11版)京东月销量好评率98%无理由退换京东配送官方店¥74.5购买编写售票任务类:
classTicketTaskimplementsRunnable{
intticket=20;
Overridepublicvoidrun(){
doTicket();
}
publicvoiddoTicket(){
while(true){
if(ticket=0)break;
System.out.println(ticket--);
}
}
编写售票测试方法:
publicstaticvoidmain(String[]args){
TicketTasktask=newTicketTask();
Threadt1=newThread(task);
Threadt2=newThread(task);
Threadt3=newThread(task);
t1.start();
t2.start();
t3.start();
案例2:模拟多个线程同时执行计数操作
classCounter{
privateintcount;
publicvoiddoCount(){
count++;
}
(1)多个线程并发执行。
(2)多个线程并发执行时存在共享数据集(临界资源)。
(3)多个线程在共享数据集上的操作不是原子操作(不可拆分的一个操作)
案例:
设计一线程安全的计数器
设计一线程安全的容器(Container)
对共享进行限制(阻塞)访问(例如加锁:syncronized,Lock):多线程在同步方法或同步代码块上排队执行。
基于CAS(比较和交换)实现非阻塞同步(基于CPU硬件技术支持)
(a)内存地址(V)
(b)期望数据值(A)
(c)需要更新的值(B)
CAS算法支持无锁状态下的并发更新,但可能会出现ABA问题,长时间自旋问题。
取消共享,每个线程一个对象实例(例如threadlocal)
(a)Connection允许多线程共享吗?(不允许,每个线程一个)
(b)SimpleDateFormat允许多线程共享吗?(不允许,每个线程一个)
(c)SqlSession对象允许共享吗?(不允许,每个线程一个)
说明:
Java中的线程安全问题的主要