CountDownLatch详解
之前我们通过讨论ReentrantLock学习到了AQS的核心、公平与非公平锁的实现以及Condition的实现原理。但是之前所涉及到的都是非共享锁,也就是独占锁。今天我们来讨论基于AQS的共享模式实现的CountDownLatch组件。本文大体上会分为两部分进行讨论。第一部分为介绍CountDownLatch的使用,第二部分将通过源码来分析CountDownLatch的实现原理。 1. CountDownLatch的使用CountDownLatch是一个使用频率非常高的类, 是AQS共享模式的典型应用。它的名字翻译过来为:倒计时门闩。具体的使用如下所示: 123456789101112131415161718192021222324252627282930313233class Driver2 { // ... void main() throws InterruptedException { CountDownLatch doneSignal = new CountDownLatch(N); Executor e = ...
Deep Packet A Novel Approach For Encrypted Traffic Classification Using Deep Learning
论文提出的方案称为“深度包”(deep packet),可以处理网络流量分类为主要类别(如FTP和P2P)的流量表征,以及需要终端用户应用程序(如BitTorrent和Skype)识别的应用程序识别。与现有的大多数方法不同,深度报文不仅可以识别加密流量,还可以区分VPN网络流量和非VPN网络流量。网络架构基于CNN与SAE,能同时进行应用识别与流量类型的分类任务。 1、介绍 准确的流量分类已成为提供适当的服务质量(quality of service, QoS)、异常检测等高级网络管理任务的先决条件之一。流量分类在与网络管理相关的学术界和工业界都引起了极大的兴趣。 本文贡献: 在Deep Packet中,不需要专家来提取与网络流量相关的特征。这种方法省去了查找和提取特征的繁琐步骤。(只要是基于DL的方法都能做到这一点) Deep Packet可以在两个粒度级别(应用程序识别和流量表征)上识别流量,并获得最先进的结果。 深度数据包可以准确地分类最难的一类应用程序,已知是P2P。 2、相关工作 Port-based approach(基于端口):提取过程简单,端口号不受...
CyclicBarrier详解
之前的文章中讨论过了[[CountDownLatch详解| CountDownLatch]]的使用方法和原理。今天再来讨论一下CyclicBarrier,CyclicBarrier的使用场景其实和CountDownLatch非常相似,用法也非常像,唯一地区别就是,不像CountDownLatch那样用一次就没了,CyclicBarrier可以重复使用。就像它名字的含义:“可以重复使用的栅栏”。今天将依然分别从它的使用和原理进行讨论。 1. CyclicBarrier的使用首先看看JavaDoc中给出的例子: 12345678910111213141516171819202122232425262728293031323334353637383940414243class Solver { final int N; final float[][] data; final CyclicBarrier barrier; class Worker implements Runnable { int myRow; Worker(int ...
InnoDB中MVCC的实现原理
MVCC 在 MySQL InnoDB 中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读。 本文将从以下几点进行讨论: 前置知识介绍; MVCC的原理; MVCC相关的问题 1. 前置知识介绍1.1 快照读和当前读当前读:像 select lock in share mode (共享锁), select for update; update; insert; delete (排他锁)这些操作都是一种当前读。就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。 快照读: 不加锁的select操作就是快照读,即不加锁的非阻塞读。是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本。 注意:快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读。 1.2 当前读,...
Git常用命令
tags: 开发工具/git Git命令集合1. 提前配置12git config --global user.name USERNAME #配置用户名git config --global user.email USEREMAIL #配置用户邮箱 2. 提交步骤12345git init #初始化git仓库git status #查看文件状态git add #添加到缓存区,追踪文件git commit -m MESSAGE #提交信息,向仓库中提交代码git log #查看提交记录 3. Git撤销123git checkout FILENAME #用暂存区的文件覆盖工作目录中的文件git rm --cached FILENAME #将文件从暂存区删除git reset --hard COMMITID #将git仓库中指定的更新记录恢复出来,并覆盖暂存区和工作目录 4. Git分支1234567git branch #查看分支git branch 分支名称 #创建分支git checkout 分支名称 #切换分支git merg...
JVM中的引用
JVM中的引用有五种,分别是:强引用、软引用、弱引用、虚引用、终结器引用(引用强度逐渐减弱)。区分这几种引用的主要原因是可以根据不同强度的引用来使用不同的垃圾回收策略。 1. 强引用(Strongly Reference)JVM中的默认的引用关系就是强引用,即对象被局部变量、静态变量等GC Root关联的对象引用,只要这层关系存在,普通对象就不能被回收。 2. 软引用(Soft Reference)软引用的引用强度弱于强引用,当一个程序的内存不足时,就会将软引用中的数据进行回收。 软引用主要用于实现缓存。如: 12345678910111213141516public class MyCache { private static Map<Integer, SoftReference<Object>> cache = new ConcurrentHashMap<>(); public static Map<Integer, SoftReference<Object>> getIns...
JVM介绍及结构
1. 什么是JVM?JVM指的是Java虚拟机,本质上是一个运行在计算机上的程序,负责运行Java字节码文件。充当一个适配器的角色,以实现Java跨平台的特性。 1.1 JVM的功能 解释执行字节码指令 管理内存中对象的分配,完成自动的垃圾回收 优化热点代码以提升效率(JIT) 1.2 JVM的组成总体分为,类加载子系统、运行时数据区、执行引擎、本地方法接口四部分。如图: 2. 运行时数据区组成运行时数据区指的是JVM所管理的内存区域。按照是否线程共享分类,分为两类: 线程共享: 方法区、堆 线程不共享: 本地方法栈、虚拟机栈、程序计数器 如下图所示: 2.1 程序计数器(Program Counter Register)也叫PC寄存器,每个线程通过PC来记录当前要执行的字节码地址。主要作用有两个: 用于控制程序指令的进行,实现分支、跳转、异常等逻辑; 多线程下,JVM通过PC记录线程切换钱执行到哪一句指令,并继续解释执行。 2.2 虚拟机栈数据结构如其名,采用栈结构来管理方法调用中的基本数据,每个方法调用采用一个栈帧来保存。每个线程都会包含自己的虚拟机栈。因此,生...
Java内存模型(JMM)
本文要讨论的是Java内存模型(JMM)。它的名字和JVM内存结构(见[[运行时内存详解]])很像,但是他们两个并不在一个层面,解决的问题也不一样。 Java 内存模型定义了 Java 语言如何与内存进行交互,具体地说是 Java 语言运行时的变量,如何与我们的硬件内存进行交互的。 而 JVM 内存模型,指的是 JVM 内存是如何划分的。 JMM是并发编程的基础,只有对JMM有一定了解才能更好的理解Java的一些高级特性,如:volatile等。因此本文将从以下几点进行讨论: 为什么要有Java内存模型? Java内存模型是什么? 并发编程的三个重要特性 1. 为什么要有Java内存模型?Java是从JDK1.5之后才开始使用新的Java内存模型。一般来说,编程语言是可以直接使用操作系统的内存模型的。但是由于Java是一个跨平台的语言,要求JVM层面屏蔽掉不同操作系统和不同硬件的差异。因此自定义了一套Java内存模型。 Java虚拟机规范中定义的Java内存模型(Java Memory Model,JMM),用于屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java...
InnoDB中的Change Buffer是个啥?
Change Buffer 是作为InnotDB的一个优化技术,用于减少对MySQL的磁盘IO操作,从而提升磁盘性能。本文将从一个解决问题的角度来了解一下Change Buffer是个啥。 1. Change Buffer总览众所周知,存储引擎瓶颈有很大一部分来源于对磁盘的随机IO操作。那么对于频繁的随机磁盘IO操作有哪些优化方案呢? 一般情况下,最常见的思路就是,直接加一层读缓存即可,此方案实现起来并不是很复杂。 但是,如果能让写请求也减少与磁盘的IO操作,那性能不是能再提升一步吗?没错,Change Buffer就是针对此方案的成果。整体的结构总览如下: 官方文档中,对Change Buffer的定义如下:更改缓冲区是一种特殊的数据结构,当二级索引页不在缓冲池中时,它会缓存对二级索引页的更改。可能由INSERT、UPDATE或DELETE(DML) 操作导致的缓冲更改,稍后在其他读取操作将页面加载到缓冲池时合并。 注意: 这里为什么声明了二级索引?不要着急,后面会解释。 接下来我们看看它的工作流程。 2. Change Buffer的工作流程假定一个场景,要对...
Java的对象头结构
对象除了我们自定义的一些属性外,在HotSpot虚拟机中,对象在内存中还可以分为三个区域:对象头、实例数据、对齐填充,这三个区域组成起来才是一个完整的对象。本文将对于对象头部分的结构进行讨论。 1. 对象的内存布局对象在内存中可以分为三个区域,分别为对象头、实例数据、对齐填充。 对象头: 为本文的讨论重点,下文将会讨论; 实例数据: 存放类的属性数据信息,包括父类的属性信息; 对齐填充: 由于虚拟机要求 对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐。 2. 对象头对象头中存储了对象是很多java内部的信息,如hash码、对象所属的年代、对象锁、锁状态标志、偏向锁(线程)ID、偏向时间等,Java对象头一般占有2个机器码。 在32位虚拟机中,1个机器码等于4字节,也就是32bit,在64位虚拟机中,1个机器码是8个字节,也就是64bit 其中,如果对象是数组类型,则需要三个机器码。因为JVM虚拟机可以通过Java对象的元数据信息确定Java对象的大小,但是无法从数组的元数据来确认数组的大小,所以用一块区域用来记录数组长度。 HotSp...