● 编程语言
武哥聊编程
同济大学硕士,第一批华为5G研发人员,拼多多广告投放部门,全网20w+粉丝。微信公众号:武哥聊编程
展开
-
java集合框架11——TreeMap和源码分析(二)
我们继续分析TreeMap的源码1.TreeMap源码分析(续)1. 存取方法 TreeMap中的存取方法本质上就是对红黑树的插入和删除操作,从源码里体现的更为明显,其实就是对红黑树的插入和删除(可以参考:红黑树),下面简单看下源码:/*************************** put和remove ****************************原创 2016-04-25 13:12:26 · 6007 阅读 · 1 评论 -
【java并发】原子性操作类的使用
在java5以后,我们接触到了线程原子性操作,也就是在修改时我们只需要保证它的那个瞬间是安全的即可,经过相应的包装后可以再处理对象的并发修改,本文总结一下Atomic系列的类的使用方法,其中包含: 类型 Integer Long 基本类型 AtomicInteger AtomicLong AtomicBoolean 数组类型 AtomicIntegerArra原创 2016-06-01 21:42:37 · 9646 阅读 · 2 评论 -
【java并发】多个线程间共享数据
先看一个多线程间共享数据的问题: 设计四个线程,其中两个线程每次对data增加1,另外两个线程每次对data减少1。 从问题来看,很明显涉及到了线程间通数据的共享,四个线程共享一个data,共同操作一个data。我们先把上面这个问题放在一边,慢慢分析多个线程之间共享数据的一些情况,从最简单开始,分类分析完了后,到时候也好解决上面这个问题了。1. 每个线程执行的任务相同 这原创 2016-05-31 22:56:36 · 20763 阅读 · 6 评论 -
【java并发】ThreadLocal类以及应用技巧
上一节总结了一下,线程范围内的数据共享问题,即定义一个Map,将当前线程名称和线程中的数据以键值对的形式存到Map中,然后在当前线程中使用数据的时候就可以根据当前线程名称从Map中拿到当前线程中的数据,这样就可以做到不同线程之间数据互不干扰。其实ThreadLocal类就是给我们提供了这个解决方法,所以我们完全可以用ThreadLocal来完成线程范围内数据的共享。public class Thre原创 2016-05-30 22:13:58 · 5170 阅读 · 14 评论 -
【java并发】造成HashMap非线程安全的原因
0. 写在前面 在前面我的一篇总结线程范围内共享数据文章中提到,为了数据能在线程范围内使用,我用了HashMap来存储不同线程中的数据,key为当前线程,value为当前线程中的数据。我取的时候根据当前线程名从HashMap中取即可。 因为当初学习HashMap和HashTable源码的时候,知道HashTable是线程安全的,因为里面的方法使用了synchronized进行同步,但是Has原创 2016-05-31 11:18:19 · 18062 阅读 · 1 评论 -
【java并发】Callable与Future的应用
Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。而Callable可以返回一个结果,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值,下面来看一个简单的例子:public class CallableAndFuture { public st原创 2016-06-03 19:11:55 · 6186 阅读 · 5 评论 -
【java并发】线程锁技术的使用
Lock锁好比传统线程模型中的synchronized技术,但是比sychronized方式更加面向对象,与生活中的锁类似,锁本身也应该是个对象。两个线程执行的代码片段如果要实现同步互斥的效果,它们必须用同一个Lock对象。锁是上在代表要操作的资源的类的内部方法中,而不是线程代码中。这一篇博文主要总结一下线程技术中Lock锁的使用。1. Lock的简单使用 有了synchronize原创 2016-06-04 07:52:09 · 13929 阅读 · 12 评论 -
【java并发】条件阻塞Condition的应用
Condition将Object监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意Lock实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了synchronized方法和语句的使用,Condition替代了Object监视器方法的使用。1. Condition的基本使用 由于Condition可原创 2016-06-04 16:38:45 · 7200 阅读 · 5 评论 -
【java并发】线程同步工具Semaphore的使用
Semaphore通常用于限制可以访问某些资源(物理或逻辑的)的线程数目,我们可以自己设定最大访问量。它有两个很常用的方法是acquire()和release(),分别是获得许可和释放许可。 官方JDK上面对Semaphore的解释是这样子的: 一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个acquire(),然后再获取该许可。每个release(原创 2016-06-05 10:00:54 · 9498 阅读 · 3 评论 -
【java并发】线程同步工具CyclicBarrier的使用
上一节中总结了Semaphore同步工具的使用,Semaphore主要提供了一个记数信号量,允许最大线程数运行。CyclicBarrier是另一个同步工具,这一节主要来总结一下CyclicBarrier的使用。先看一下官方的对CyclicBarrier的介绍: 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的原创 2016-06-05 21:13:09 · 4319 阅读 · 2 评论 -
【java并发】线程同步工具Exchanger的使用
如果两个线程在运行过程中需要交换彼此的信息,比如一个数据或者使用的空间,就需要用到Exchanger这个类,Exchanger为线程交换信息提供了非常方便的途径,它可以作为两个线程交换对象的同步点,只有当每个线程都在进入 exchange ()方法并给出对象时,才能接受其他线程返回时给出的对象。 每次只能两个线程交换数据,如果有多个线程,也只有两个能交换数据。下面看个通俗的例子:一手交钱一首原创 2016-06-06 09:48:12 · 4954 阅读 · 8 评论 -
【java并发】阻塞队列的使用
在前面一篇名为条件阻塞Condition的应用的博客中提到了一个拔高的例子:利用Condition来实现阻塞队列。其实在java中,有个叫ArrayBlockingQueue的类提供了阻塞队列的功能,所以我们如果需要使用阻塞队列,完全没有必要自己去写。 ArrayBlockingQueue实现了BlockingQueue,另外还有LinkedBlockingQueue和PriorityBlo原创 2016-06-07 09:27:34 · 7893 阅读 · 3 评论 -
【java并发】线程范围内共享数据
假设现在有个公共的变量data,有不同的线程都可以去操作它,如果在不同的线程对data操作完成后再去取这个data,那么肯定会出现线程间的数据混乱问题,因为A线程在取data数据前可能B线程又对其进行了修改,下面写个程序来说明一下该问题:原创 2016-05-30 09:11:02 · 5881 阅读 · 8 评论 -
【java虚拟机】java内存区域与内存溢出异常
本文参考自《深入理解Java虚拟机》一书。主要总结一下java虚拟机内存的各个区域,以及这些区域的作用、服务对象以及其中可能产生的问题。1. 运行时数据区域 java虚拟机在执行java程序的过程中会把它说管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。具体如下图所示:原创 2016-06-30 07:22:29 · 6621 阅读 · 14 评论 -
【java虚拟机】java虚拟机的类加载机制
这篇博文主要来总结一下java虚拟机加载一个类的过程,为了避免枯燥的解说,为了让读者在读完本文后能彻底理解类加载的过程,首先来看一段java代码,我们从一个例子入手://ClassLoaderProcess.java文件class Singleton { private static Singleton singleton = new Singleton(); public原创 2016-07-01 08:24:50 · 8021 阅读 · 25 评论 -
【C/C++】C++对C的扩展总结
之前一直在搞java开发,去年9月份开始,陆陆续续的公司来学校校招了,然后开始忙于校招。后来去了华为,签了约后开始写大论文,所以之后就一直没有更新自己的博客了,有些朋友留言说博客懒惰了,好久没写博客了~哈哈!现在大论文也差不多了,是时候继续学习了。 由于签了华为,岗位是通信设备软件开发,再加上之前有一周的培训,我估计后面基本上是要做C/C++了,其实我挺喜欢做java的,但是没办法。C++我在三原创 2017-02-21 18:32:31 · 6571 阅读 · 7 评论 -
【C/C++】C++中函数重载原理
C++中的函数重载大家并不陌生,也经常使用。这篇博文首先简单介绍一下重载的规则与调用匹配,然后介绍一下重载的底层原理,最后再介绍一下 extern “C”的使用。1. 重载规则与调用匹配1.1 重载规则首先来看下函数的重载规则,这个比较简单,如下: 函数名要相同。 参数个数不同,参数的类型不同,参数顺序不同,均可构成重载。 返回值类型不同则不可以构成重载。 如下:void f原创 2017-02-22 15:09:47 · 5947 阅读 · 13 评论 -
【java并发】线程并发库的使用
1. 线程池的概念 在java5之后,就有了线程池的功能了,在介绍线程池之前,先来简单看一下线程池的概念。假设我开了家咨询公司,那么每天会有很多人过来咨询问题,如果我一个个接待的话,必然有很多人要排队,这样效率就很差,我想解决这个问题,现在我雇几个客服,来了一个咨询的,我就分配一个客服去接待他,再来一个,我再分配个客服去接待……如果第一个客服接待完了,我就让她接待下一个咨询者,这样我雇的这些客服可原创 2016-06-02 21:15:09 · 8802 阅读 · 5 评论 -
【java并发】一道多线程问题
前面几篇博文基本上总结了一下java并发里的一些内容,下面通过几个练习题巩固一下。 题目描述: 模拟一个场景:处理16条日志记录,每条日志记录打印时间需要1秒,正常情况下如果将这16条记录去部打完需要16秒,现在为了提高效率,准备开启4个线程去打印,4秒钟打印完,实现这个demo。 先来分析一下这个题目,关于这16条日志记录,我们可以在主线程中产生出来,这没用什么难度,关键是原创 2016-06-07 17:29:59 · 4854 阅读 · 7 评论 -
java集合框架10——TreeMap和源码分析(一)
前面讨论完了HashMap和HashTable的源码,这一节我们来讨论一下TreeMap。先从整体上把握TreeMap,然后分析其源码,深入剖析TreeMap的实现。1. TreeMap简介 TreeMap是一个有序的key-value集合,它内部是通过红-黑树实现的,如果对红-黑树不太了解,请先参考下这篇博文:红-黑树。下面我们先来看看TreeMap的继承关系:java原创 2016-04-25 09:14:52 · 4780 阅读 · 2 评论 -
java集合框架07——Map架构与源码分析
前几节我们对Collection以及Collection中的List部分进行了分析,Collection中还有个Set,由于Set是基于Map实现的,所以这里我们先分析Map,后面章节再继续学习Set。首先我们看下Map架构图: 从图中可以看出: 1. Map是一个接口,Map中存储的内容是键值对(key-value)。 2. 为了方便原创 2016-04-14 17:16:08 · 7499 阅读 · 1 评论 -
java集合框架03——ArrayList和源码分析
上一章学习了Collection的架构,并阅读了部分源码,这一章开始,我们将对Collection的具体实现进行详细学习。首先学习List。而ArrayList又是List中最为常用的,因此本章先学习ArrayList。先对ArrayList有个整体的认识,然后学习它的源码,深入剖析ArrayList。1. ArrayList简介 首先看看ArrayList与Collecti...原创 2016-04-11 15:05:57 · 6825 阅读 · 5 评论 -
java集合框架04——LinkedList和源码分析
上一章学习了ArrayList,并分析了其源码,这一章我们将对LinkedList的具体实现进行详细的学习。依然遵循上一章的步骤,先对LinkedList有个整体的认识,然后学习它的源码,深入剖析LinkedList。LinkedList简介 首先看看LinkedList与Collection的关系:原创 2016-04-12 18:53:35 · 5814 阅读 · 2 评论 -
java集合框架02——Collection架构与源码分析
Collection是一个接口,它主要的两个分支是List和Set。如下图所示: List和Set都是接口,它们继承与Collection。List是有序的队列,可以用重复的元素;而Set是数学概念中的集合,不能有重复的元素。List和Set都有它们各自的实现类。为了方便,我们抽象出AbstractCollection类来让其他类继承,该类实现类Collection中的绝...原创 2016-04-13 08:21:49 · 13462 阅读 · 10 评论 -
java集合框架05——ArrayList和LinkedList的区别
前面已经学习完了List部分的源码,主要是ArrayList和LinkedList两部分内容,这一节主要总结下List部分的内容。List概括先来回顾一下List在Collection中的的框架图:从图中我们可以看出:1. List是一个接口,它继承与Collection接口,代表有序的队列。2. AbstractList是一个抽象类,它继承与AbstractColle原创 2016-04-13 20:39:09 · 107426 阅读 · 41 评论 -
java集合框架06——fail-fast机制
在JDK的Collection中我们时常会看到类似于这样的话: 例如,ArrayList:注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失转载 2016-04-14 10:06:58 · 3118 阅读 · 1 评论 -
java集合框架09——HashTable和源码分析
上一章我们学习了HashMap的源码,这一节我们来讨论一下HashTable,HashTable和HashMap在某种程度上是类似的。我们依然遵循以下步骤:先对HashTable有个整体的认识,然后学习它的源码,深入剖析HashTable。1.HashTable简介 首先看一下HashTable的继承关系java.lang.Object ↳ java.uti原创 2016-04-21 20:04:27 · 4323 阅读 · 7 评论 -
java集合框架08——HashMap和源码分析
上一章总体分析了Map架构,并简单分析了一下AbstractMap源码,这一章开始我们将对Map的具体实现类进行详细的学习。本章先研究HashMap。依然遵循以下步骤:先对HashMap有个整体的认识,然后学习它的源码,深入剖析HashMap。原创 2016-04-15 23:40:56 · 10344 阅读 · 6 评论 -
java集合框架12——HashMap和HashTable的区别
前面已经学习了Map的部分内容,主要是HashMap和HashTable,这一节我们来看看它们两有啥异同点。1. HashMap和HashTable的相同点 HashMap和HashTable都是存储“键值对”的散列表,而且都是采用拉链法来实现的。存储的思想都是:通过table数组存储,数组的每个元素都是一个Entry,而一个Entry就是一个单项链表,Entry链表中的每个原创 2016-04-26 15:50:35 · 5195 阅读 · 5 评论 -
【java并发】传统线程同步通信技术
先看一个问题: 有两个线程,子线程先执行10次,然后主线程执行5次,然后再切换到子线程执行10,再主线程执行5次……如此往返执行50次。 看完这个问题,很明显要用到线程间的通信了, 先分析一下思路:首先肯定要有两个线程,然后每个线程中肯定有个50次的循环,因为每个线程都要往返执行任务50次,主线程的任务是执行5次,子线程的任务是执行10次。线程间通信技术主要用到wait()方法和n原创 2016-05-29 11:50:59 · 7006 阅读 · 6 评论 -
【java并发】线程技术之死锁问题
我们知道,使用synchronized关键字可以有效的解决线程同步问题,但是如果不恰当的使用synchronized关键字的话也会出问题,即我们所说的死锁。死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 下面写一个死锁的例子加深理解。先看程序,再来分析一下死锁产生的原因:public class DeadL原创 2016-05-29 09:52:23 · 6043 阅读 · 11 评论 -
【java并发】传统线程互斥技术—synchronized
在多个线程同时操作相同资源的时候,就会遇到并发的问题,如银行转账啊、售票系统啊等。为了避免这些问题的出现,我们可以使用synchronized关键字来解决,下面针对synchronized常见的用法做一个总结。首先写一个存在并发问题的程序,如下:public class TraditionalThreadSynchronized { public static void main(String原创 2016-05-28 16:44:50 · 6594 阅读 · 3 评论 -
【java并发】传统线程技术中的定时器技术
传统线程技术中有个定时器,定时器的类是Timer,我们使用定时器的目的就是给它安排任务,让它在指定的时间完成任务。所以先来看一下Timer类中的方法(主要看常用的TimerTask()方法):原创 2016-05-28 12:29:34 · 5028 阅读 · 1 评论 -
【java并发】传统线程技术中创建线程的两种方式
传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法;二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread。这两种方式大部分人可能都知道,但是为什么这样玩就可以呢?下面我们来详细分析一下这两种方法的来龙去脉。1. 揭秘Thread中run()方法 上面我们看到这两种方式都跟run()方法有关,所以我们来看一原创 2016-05-21 17:02:19 · 7327 阅读 · 4 评论 -
小心踩雷,一次Java内存泄漏排查实战
“前些日子小组内安排值班,轮流看顾我们的服务,主要做一些报警邮件处理、Bug 排查、运营 issue 处理的事。工作日还好,无论干什么都要上班的,若是轮到周末,那这一天算是毁了。不知道是公司网络广了就这样还是网络运维组不给力,网络总有问题,不是这边交换机脱网了,就是那边路由器坏了,还偶发地各种超时,而我们灵敏的服务探测服务总能准确地抓住偶现的小问题,给美好的工作加点料。...转载 2019-06-04 08:45:00 · 8529 阅读 · 8 评论