0%

一 Linux 的 5 种 主要 IO 模式

实现高性能的网络应用框架离不开 I/O 模型问题,在了解 Netty 前先了解 I/O 模型的基本知识。

I/O 请求可以分为两个阶段,分别为调用阶段和执行阶段。

  • 第一个阶段为I/O 调用阶段,即用户进程向内核发起系统调用。
  • 第二个阶段为I/O 执行阶段。此时,内核等待 I/O 请求处理完成返回。该阶段分为两个过程:首先等待数据就绪,并写入内核缓冲区;随后将内核缓冲区数据拷贝至用户态缓冲区。
阅读全文 »

概述

HTTP 协议中有可能存在信息窃听或身份伪装等安全问题。使用 HTTPS 通信机制可以有效地防止这些问题。

HTTP 的缺点

HTTP 主要有这些不足:

  • 通信使用明文(不加密),内容可能会被窃听
  • 不验证通信方的身份,因此有可能遭遇伪装
  • 无法证明报文的完整性,所以有可能已遭篡改
阅读全文 »

TCP/IP 的分层管理

TCP/IP 协议族里重要的一点就是分层。TCP/IP 协议族按层次分别分 为以下 5 层:应用层、传输层、网络层和数据链路层、物理层。

  • 应用层决定了向用户提供应用服务时通信的活动。 TCP/IP 协议族内预存了各类通用的应用服务。比如,FTP(File Transfer Protocol,文件传输协议)和 DNS(Domain Name System,域 名系统)服务就是其中两类。 HTTP 协议也处于该层。

  • 传输层 传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据 传输。 在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Data Protocol,用户数据报 协议)。

  • 网络层(又名网络互连层) 网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数 据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计 算机,并把数据包传送给对方。 与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所 起的作用就是在众多的选项内选择一条传输路线。

  • 数据链路层(又名数据链路层,网络接口层) 用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱 动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等 物理可见部分(还包括连接

  • 物理层(physical layer)的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异, 使其上面的数据链路层不必考虑网络的具体传输介质是什么。

bc6f6efadbc09277c27adb63c25488b8.png

阅读全文 »

线程安全的实现方法概述

线程安全的实现方法,可以分为 阻塞同步,非阻塞同步,无同步方案三大类:

58567e99523dabb30de128bae6916038.png

其中阻塞同步最基本的两个实现手段就是通过 synchronized 或 ReentrantLock 关键字。这篇文章主要记录下 RentrantLock 的源码实现。

ReentrantLock 是基于 抽象类 AbstractQueuedSynchronizer 实现的,AQS内部使用了一个volatile的变量state 来作为资源的标识,并提供了一些模版方法,ReentrantLock 通过实现 AQS 的 tryAcquire 实现获取锁的逻辑。

阅读全文 »

ThreadLocal 用来解决什么

如果一段代码中所需要的数据必须与其他代码共享,并且共享数据的代码能保证在同一个线程中执行,那我们就可以通过ThreadLocal 来把共享数据的可见范围限制在同一个线程之内,这样的好处是,不需要同步也能保证线程之间不出现数据争用问题。

变量既需要在方法或类之间共享,又期望在线程间隔离的场景,就非常适合使用 ThreadLocal 来实现。

阅读全文 »

阻塞队列的由来

在生产者-消费者模式中,为了使生产者消费者解藕,需要一个存放元素的容器,使生产者可以只关心往队列里添加元素下,消费者只关系从队列中取出元素进程处理。

而且这个队列必须要满足两点:

  • 线程安全
  • 缓冲池空了,我们需要阻塞消费者,唤醒生产者;当缓冲池满了,我们需要阻塞生产者,唤醒消费者

JDK 为此设计了 阻塞队列(BlockingQueue),并提供了几个基于 BlockingQueue 接口 实现的一些线程安全的阻塞队列。

阅读全文 »

为什么要使用线程池

池化技术相比大家已经屡见不鲜了,线程池、数据库连接池、Http 连接池等等都是对这个思想的应用。池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。

这里借用《Java 并发编程的艺术》提到的来说一下使用线程池的好处:

  • 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  • 提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
  • 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
阅读全文 »

AQS

AQS 简介

AQS是AbstractQueuedSynchronizer的简称,即抽象队列同步器,从字面意思上理解:

  • 抽象:抽象类,只实现一些主要逻辑,有些方法由子类实现;
  • 队列:使用先进先出(FIFO)队列存储数据;
  • 同步:实现了同步的功能。

AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的同步器,比如我们常用到的同步类 ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier,ReentrantReadWriteLock,SynchronousQueue,FutureTask等等皆是基于AQS的。

阅读全文 »

乐观锁与悲观锁的概念

锁可以从不同的角度分类。其中,乐观锁和悲观锁是一种分类方式。

悲观锁:
悲观锁就是我们常说的锁。对于悲观锁来说,它总是认为每次访问共享资源时会发生冲突,所以必须对每次数据操作加上锁,以保证临界区的程序同一时间只能有一个线程在执行。互斥同步锁就属于悲观锁,比如, synchronized. 与 ReentrantLock.

乐观锁:
乐观锁又称为“无锁”,顾名思义,它是乐观派。乐观锁总是假设对共享资源的访问没有冲突,线程可以不停地执行,无需加锁也无需等待。而一旦多个线程发生冲突,乐观锁通常是使用一种称为CAS的技术来保证线程执行的安全性。

由于无锁操作中没有锁的存在,因此不可能出现死锁的情况,也就是说乐观锁天生免疫死锁。

阅读全文 »