2021-01-06

本文介绍了JAVA内存模型(JMM)及其解决的线程通信和同步问题,强调了JMM与JAVA内存区域的区别。详细阐述了重排序的概念及其对多线程语义的影响,以及JMM如何通过happens-before原则保证一致性。volatile关键字的作用在于保证内存可见性和禁止重排序,其在并发编程中提供了轻量级锁的特性。最后,简要提及了HTTP协议栈的工作流程。
摘要由CSDN通过智能技术生成

一、JAVA内存模型
1、并发编程的两个问题
线程之间以何种机制来交换信息——>线程如何通信
线程之间以何种机制来控制不同线程间操作发生的相对顺序——>线程如何同步
a.解决方案
消息传递并发模型
共享内存并发模型
在这里插入图片描述

2、JAVA内存模型的抽象结构
a.运行时内存的划分
在这里插入图片描述

栈中的变量(局部变量、方法定义参数、异常处理器参数)不会在线程之间共享;而堆中的变量是共享的,存在可见性的问题;
b.堆中的内存不可见问题
线程之间的共享变量存在内存中,每个线程都有一个私有的本地内存,存储了该线程以读、写共享变量的副本。本地内存是java内存模型的一个抽象概念,并不真实存在,涵盖了缓存、写缓冲区、寄存器等;
c.JMM(JAVA内存模型 )
在这里插入图片描述

线程A无法直接访问线程B的工作内存,线程间通信必须经过主内存;JMM规定线程对共享变量的所有操作都必须在自己的本地内存中进行,不能直接从主内存中读取;
d.JMM与JAVA内存区域的区别和联系
两者是不同的层次概念。JMM是抽象的,描述一致规则;而JAVA运行时内存是具体的,是必要的内存划分。一般来说,JMM中的主内存属于共享数据区域,包含堆和方法区;JMM中的本地内存属于私有数据区,包含了程序计数器、本地方法栈、虚拟机栈;
二、重排序和happens-before
1、重排序
为提高性能,计算机在执行程序时,编译器和处理器对指定做重排操作。主要解决为节约时间而产生的流水线技术害怕的程序中断;
a.指令重排
编译器优化重排(编译器)
在不改变单线程程序语义的前提下,重新安排语句的执行顺序;
指令并行重排(CPU)
不存在数据依赖性情况下,处理器改变语句对应的机器指令的执行顺序;
指令重排可以保证串行语义一致,但是没有保证多线程间的语义也一致;
2、顺序一致性模型与JMM保证
顺序一致性是一个理论参考模型;
a.数据竞争与顺序一致性
数据竞争:一个线程中写数据,另一个线程读同一个数据,并且写和读没有通过同步来排序
JMM保证,正确使用volatile、final、synchronized关键字使程序正确同步则不会出现数据竞争的问题,程序的执行将具有一致性;
b.顺序一致性模型
一个线程的操作必须按照程序的顺序(即JAVA代码的顺序)来执行;
所有线程都只能看到一个单一的操作顺序;每个操作必须是原子性的,且对所有线程可见;
但是JMM没有这样的保证。例如,在当前线程把写过的数据缓存在本地内存中,在没有刷新到主内存之前,这个写操作仅对当前线程可见,其他线程是看不到这个操作的;
c.JMM中同步程序的顺序一致性效果
JMM中,临界区(同步块或同步方法)的代码可以发生重排序,但不允许临界区内的代码逃逸到临界区之外,破坏锁的内存语义;
d.未同步程序在JMM和顺序一致性内存模型中执行差异
顺序一致性保证单线程内操作会按照程序的顺序执行;JMM不保证单线程内的操作会按照程序的顺序执行,但保证单线程下的重排序不影响执行结果;
顺序一致性模型保证所有线程只能看到一致的操作执行顺序,而JMM不保证所有线程能看到一致的操作顺序(因为JMM不保证所有操作立即可见);
JMM不保证对64位的long类型和double类型变量的写操作具有原子性,而顺序一致性模型保证对所有的内存读写操作都具有原子性;
3、happens-before
原则定义如下:
如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。此外,两个操作存在happens-before关系,并不意味则一定按照规则的顺序来执行,如果重排序之后的执行结果没有改变,那么这种重排序并不非法;
三、Volatile关键字
volatile关键字可以保证变量的内存可见性、禁止volatile变量与普通变量重排序;
1、内存可见性
所谓的内存可见性,指的是当一个线程对volatile修饰的变量进行写操作时,JMM会立即把该线程对应的本地内存中的共享变量的值刷新到主内存;当一个线程对volatile修饰的变量进行读操作时,JMM会立即把该线程对应的本地内存置为无效,从主内存中读取共享变量的值;
2、禁止重排序
禁止volatile变量与普通变量在编译器和处理器层级上发生重排序;
内存屏障(读屏障和写屏障)‘——>JVM 限制处理器的重排序
作用:
阻止屏障两侧的指令重排序;
强制把写缓冲区/高速缓存中的脏数据写回主内存,或者让缓存中的数据失效;
编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序;
在这里插入图片描述

其中,Load代表读操作,Store代表写操作
3、volatile的用途
在保证内存可见性这一点上,volatile有着与锁相同的内存语义,可以作为一个轻量级的锁来使用。但是volatile保证单个volatile变量具有原子性,而锁可以保证临界区代码的执行具有原子性。因此,在功能上,锁比volatile更强大,在性能上,volatile更具优势;
四、浏览器键入网址后发生的事情(一)
1、HTTP
浏览器解析URL(文件资源路径)
在这里插入图片描述

没有路径名时,访问根目录下事先设置的默认文件,一般是index.html;
产生HTTP请求信息
在这里插入图片描述
在这里插入图片描述

2、DNS(真实地址查询)
浏览器解析URL并生成HTTP消息后,需要委托操作系统将消息发送给web服务器。在发送之前,还需要查询服务器域名对应的IP地址。
DNS服务器专门保存了Web服务器域名与IP的对应关系;
3、协议栈
通过DNS获取IP后,就可以把HTTP的传输工作交给操作系统中的协议栈。协议栈的内部分为几个部分,分别承担不同的工作。上面的部分会向下面的部分委托工作,下面的部分受到委托的工作并执行。
在这里插入图片描述

应用程序(浏览器)通过调用socket库,来委托协议栈工作;
协议栈上半部分的TCP和UDP会接受应用层的委托执行收发数据的操作(运输层);
协议栈的下面一般IP协议控制网络包收发操作(网络层),此外工作在IP层还有ICMP和ARP协议;
IP下面的网卡驱动程序负责控制网卡硬件;
最底下的网卡负责完成实际的收发操作,也就是对网线中的信号执行发动和接收操作;
4、可靠传输TCP
a.TCP报文头部格式:
在这里插入图片描述

源端口号和目标端口号标识需要发送的应用;
序号:解决包乱序的问题;
确认号:确认发送后对方是否有收到,没有收到就应该重新发送,直到送达,解决不丢包问题;
一些状态位:SYN发起连接;ACK回复;RST重新连接;FIN结束连接;
窗口大小:用于流量控制,通信双方各声明一个窗口(缓存大小),标识自己的处理能力;处理流量控制之外,还可以实现拥塞控制,也就是控制发送的速度;
b.TCP 三次握手建立连接
三次握手是为了确保双方都有发送和接收的能力;
在这里插入图片描述

c.TCP分割数据
在这里插入图片描述

MTU:一个网络包的最大长度,以太网一般为1500字节;
MSS:除去IP和TCP头部之后,一个网络包所能容纳的TCP数据的最大长度;
数据会以MSS的长度为单位进行拆分,拆分出来的每一块数据都会被方静单独的网络包中。也就是每个被拆分的数据加上TCP头信息,然后交给IP模块来发送数据;
在这里插入图片描述

d.TCP报文生成
双方建立了连接后,TCP报文中的数据部分就是存放HTTP头部+数据;
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值