Java
服务端开发
这个作者很懒,什么都没留下…
展开
-
使用99个线程顺序打印1到99:volatile与synchronized关键字的应用
使用100个线程,顺序打印1到99。基本设计思路是:定义一个全局变量totalNum来控制当前需要打印哪个数字每个线程都使用一个顺序编号num当totalNum与num相等时,打印num,并且在该线程递增num,以便通知下一个线程打印。多线程相关:totalNum使用volatile关键字修饰保证线程可见性;每个线程内部基于synchronized关键字和基于Object类的wait方...原创 2019-09-21 15:47:53 · 2333 阅读 · 0 评论 -
Java NIO的三种Reactor线程模型分析
概述在使用Java NIO和多线程来进行高并发Java服务端应用程序设计时,通常是基于Reactor线程模型来设计的。Reactor,即包含一个Java NIO的多路复用选择器Selector的反应堆,当有反应时,即该Selector所管理的某个客户端连接有IO事件过来时,则在当前线程或者分配到其他线程来处理该IO事件。Reactor线程模型通常由接收客户端连接请求的acceptor线程和处...原创 2019-06-30 14:14:14 · 4192 阅读 · 0 评论 -
JDK1.8源码分析:线程本地变量ThreadLocal的使用与实现原理
一、概述在Java多线程编程当中,对于被多个线程的共享变量,一般的方式是通过加锁,如使用synchronized关键字或者Java并发包的ReentrantLock加锁来实现线程安全,或者该变量在Java并发包存在线程安全的版本实现,如整数Integer对应的AtomicInteger,HashMap对应的ConcurrentHashMap等,则使用对应的线程安全版本的实现。除了以上两种方式...原创 2019-06-18 14:10:23 · 5279 阅读 · 0 评论 -
JDK1.8源码分析:ForkJoin任务递归分解与并行计算框架的设计与用法
概述ForkJoin框架是在JDK1.7推出的,支持将一个大任务递归拆分成多个小任务,然后交给线程池的线程执行任务的并行处理,最后可以获取所有这些任务的执行结果并汇总。这个框架的主要设计目的就是实现任务的自动化递归拆分,然后交给线程池的线程处理,而不需要在应用代码中实现任务的递归拆分和汇总,简化了多线程环境下,递归拆解任务进行并行执行的编程难度。简单来说就是对递归算法的多线程实现,即支持每个...原创 2019-02-17 17:53:59 · 5312 阅读 · 0 评论 -
JDK1.8源码分析:ConcurrentSkipListMap-有序并发容器Map
TreeMap,ConcurrentSkipListMap和ConcurrentSkipListSet在集合框架中提供了TreeMap来实现Map的key有序,TreeMap不是线程安全的,如果多个线程对TreeMap进行结构性修改,如添加或删除操作,则需要进行同步。而在JUC包中提供了ConcurrentSkipListMap来实现一个并发、线程安全版本的TreeMap。TreeMap是基...原创 2019-02-16 23:36:57 · 7303 阅读 · 1 评论 -
JDK1.8源码分析:线程安全的CopyOnWriteArrayList与CopyOnWriteArraySet
概述ArrayList不是线程安全的,所以如果需要保证ArrayList在多线程环境下的线程安全,即保证读的线程可见性和写的数据一致性,可以使用synchronized或者ReentrantLock对ArrayList的读写进行同步,或者使用Collections.syncrhonizedList来保证成同步SynchronizedList。由于以上方法对读写都需要加锁,一定程度上影响了读写...原创 2019-02-16 18:21:29 · 5786 阅读 · 0 评论 -
JDK1.8源码分析:ScheduledExecutorService和周期性任务停止执行的原因
概述ScheduledExecutorService继承于ExecutorService,主要提供任务的延迟和周期性执行的功能。其主要提供了schedule,scheduleAtFixedRate,scheduleWithFixedDelay三个方法,分别用于延迟执行任务,特定频率周期性执行任务,特定延迟周期性执行任务。public interface ScheduledExecutorS...原创 2019-02-16 15:09:58 · 6565 阅读 · 0 评论 -
JDK1.8源码分析:Executors线程池创建工厂的用法和实现原理
概述在Executor线程执行器框架中,提供了Executors这个工具类来创建指定的Executor实现类。在Executors工具类中提供了ThreadPoolExecutor创建时所需的默认参数,通过方法名称来表明指定的实现,从而简化了ThreadPoolExecutor的创建。固定线程池,无界队列线程池的核心线程数和最大线程数固定且相同,任务等待队列无界:public st...原创 2019-02-16 12:37:30 · 6199 阅读 · 0 评论 -
JDK1.8源码分析:Future和FutureTask-任务异步执行结果
概述任务在Executor线程执行器当中是异步执行的,而有些任务是需要返回执行结果的,故在Executor派生接口ExecutorService接口中定义了带返回结果的提交方法submit,其中返回结果为Future接口的对象。Future接口主要提供了异步返回任务执行结果,取消任务执行,获取任务执行状态的功能,接口定义如下:public interface Future<V&...原创 2019-02-16 11:09:27 · 5314 阅读 · 0 评论 -
JDK1.8源码分析:Executor和ThreadPoolExecutor线程池的设计和源码实现
概述Executor线程执行器框架是在jDK1.5提供的,设计的主要目的是实现Runnable任务的提交和执行分离:任务提交主要是指在应用代码中实现Runnable接口定义业务相关的一个任务,然后交给一个Thread线程对象来执行;任务的执行是指Thread线程执行该任务。有了Executor线程执行器之后,我们只需要实现Runnalbe接口定义自己的任务即可,不需要显示创建Thread对象来...原创 2019-02-16 00:27:52 · 4876 阅读 · 1 评论 -
JDK1.8源码分析:可重入锁ReentrantLock和Condition的实现原理
synchronized的用法和实现原理synchronized实现线程同步的用法和实现原理不足synchronized在线程同步的使用方面,优点是使用简单,可以自动加锁和解锁,但是也存在一些不足:synchronized是阻塞的,不支持非阻塞,中断和超时退出特性;synchronized是互斥锁,不支持多个线程对资源的共享访问,如多个读线程进行并发读;当多个方法共享多个mo...原创 2019-02-14 13:09:35 · 6529 阅读 · 0 评论 -
synchronized实现线程同步的用法和实现原理
作用和用法在多线程对共享资源进行并发访问方面,JDK提供了synchronized关键字来进行线程同步,实现多线程并发访问的线程安全。synchronized的作用主要体现在三个方面:(1)确保线程互斥地访问同步代码;(2)保证共享变量的线程可见性;(3)禁止指令重排。其中(2)和(3)相当于volatile关键字的作用。sychronized可以用在(1)静态方法,(2)普通成员方法...原创 2019-02-14 00:06:25 · 5770 阅读 · 1 评论 -
JUC并发包基于AQS实现的线程同步器的案例分析
以下是JUC并发包提供的基于AQS实现的线程同步器。ReentrantLock:可重入锁通常用于多线程操作进行同步,实现线程安全。存在公平和非公平两种实现,默认为非公平。如在LinkedBlockingQueue中使用putLock来同步多个生产者的写操作,使用takeLock来同步多个消费者的读操作。public boolean offer(E e, long timeout, ...原创 2019-02-13 18:33:10 · 5689 阅读 · 0 评论 -
JDK1.8源码分析:ReentrantReadWriteLock可重入读写锁
概述ReentrantReadWriteLock包含读写两把锁,如下:public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }对同一线程而言,...原创 2019-02-13 15:59:57 · 4920 阅读 · 0 评论 -
JDK1.8源码分析:基于队列的线程同步器AbstractQueuedSynchronizer(AQS)
概述AQS是一个实现线程同步器的基础框架,线程同步器的作用是协调多个线程对共享资源的访问,如ReentrantLock,在多个线程共享同一个资源时,实现多线程对该共享资源的同步访问,避免并发访问导致数据不一致等问题。或者协调多个线程之间的操作,如CountDownLatch。AQS提供了基于一个FIFO队列实现线程同步器的基础设施,具体的线程同步器实现类,只需要关注对共享资源的访问控制,即是...原创 2019-02-13 00:18:42 · 5004 阅读 · 0 评论 -
JDK1.8源码分析:阻塞队列LinkedBlockingQueue与BlockingDeque(双端)的设计与实现
概述BlockingQueue:阻塞FIFO队列,在接口设计层面,对于从队列尾部添加元素,从队列头部获取并删除元素的方法,在队列满时添加元素或者队列空时获取元素,则提供了四个版本:分别是:抛异常,直接返回一个特殊值null或者false,无限阻塞直到队列不满或者队列不空,阻塞指定的时间。实现类包括:ArrayBlockingQueue(基于数组),LinkedBlockingQueue(基于...原创 2019-02-11 18:19:46 · 5038 阅读 · 0 评论 -
JDK1.8源码分析:LinkedList
接口和数据结构LinkedList,实现了List和Deque接口,其中Deque是双向队列,即可以在队列头部和尾部进行插入或删除数据节点。LinkedList也不是线程安全的。public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, ...原创 2019-02-11 12:52:52 · 4645 阅读 · 0 评论 -
JDK1.8源码分析:ArrayList
ArrayList相对于数组Array只是提供了动态拓容的功能,在内部也是使用一个数组来存储数据的。ArrayList也不是线程安全的,如果需要线程安全,则需要使用Collections.synchronziedList来进行包装,如:List list = Collections.synchronizedList(new ArrayList(…));/** * Default in...原创 2019-02-11 10:59:16 · 4770 阅读 · 2 评论 -
JDK1.8源码分析:HashSet与LinkedHashSet
HashSet内部封装了一个HashMap,利用HashMap的key来存储Set的值,然后对应的value都是一个Object实例。从而利用HashMap的key的唯一性来实现去重。// Dummy value to associate with an Object in the backing Mapprivate static final Object PRESENT = new ...原创 2019-02-09 21:00:49 · 4935 阅读 · 0 评论 -
JDK1.8源码分析:LinkedHashMap与LRU缓存设计思路
概述LinkedHashMap继承于HashMap,在HashMap的基础上,新增了两个特性:支持以节点的插入顺序来迭代该map内的所有节点,即内部维护;支持缓存设计中LRU的特性,即LinkedHashMap支持按访问顺序来排序节点,具体在内部实现了如果开启了这个特性,则每个通过get方法访问了一个节点,则该节点会被移动到内部的双向链表的末尾,故双向链表的头结点是最近最少访问的节点,...原创 2019-02-09 18:25:24 · 5238 阅读 · 0 评论 -
JDK源码分析:ConcurrentHashMap(JDK1.8版本)
概述在JDK1.7主要通过定义Segment分段锁来实现多个线程对ConcurrentHashMap的数据的并发读写操作。整个ConcurrentHashMap由多个Segment组成,每个Segment保存整个ConcurrentHashMap的一部分数据,Segment结合ReentrantLock,即Segment继承于ReentrantLock,来实现写互斥,读共享,具体为有多少个Se...原创 2019-02-09 01:14:52 · 5584 阅读 · 1 评论 -
JDK源码分析:ConcurrentHashMap(JDK1.7版本)
主文章:JDK源码分析:ConcurrentHashMap(JDK1.7和JDK1.8)与HashTableSegment:分段锁在HashMap中,是使用一个哈希表,即元素为链表结点Node组成的数组table,而在ConcurrentHashMap中是使用多个哈希表,具体为通过定义一个Segment来封装这个哈希表其中Segment继承于ReentrantLock,故自带lock的功...原创 2019-02-08 18:12:52 · 6034 阅读 · 1 评论 -
JDK源码分析:ConcurrentHashMap(JDK1.7和JDK1.8),HashTable与Collections.synchronizedMap
概述ConcurrentHashMap是线程安全的HashMap,提供与HashTable一样的线程安全特性。与HashMap不同的是,除了线程安全之外,HashMap的key和value都支持null,而HashTable和ConcurrentHashMap的key和value都不允许是null。与HashTable不同的是,ConcurrentHashMap不需要对所有需要线程安全保证...原创 2019-02-08 18:10:48 · 5151 阅读 · 0 评论 -
JDK1.8源码分析:HashMap
数据结构在JDK1.8之前,HashMap是基于链式哈希实现的,而在JDK1.8之后,为了提高冲突节点的访问性能,在链式哈希实现的基础上,在哈希表大小超过64时,针对冲突节点链条,如果节点数量超过8个,则升级为红黑树,小于等于6个时,则降级为链表结构。链式哈希链式哈希是一个数组结构,数组元素为链表或者红黑树。如下为HashMap的内部数据存储结构,也是链式哈希的实现。其中Node为一...原创 2019-02-07 12:41:36 · 5271 阅读 · 0 评论 -
JDK1.8源码分析:NIO缓冲区Buffer
概念Buffer接口是Java NIO的缓冲区的基础接口,定义了缓冲区操作的相关控制属性和操作方法。缓冲区是一个存放特定基础类型数据,如byte, char, int, long, float, double(不能是boolean),的容器,物理上是一个有界的线性数组。Buffer接口的具体实现类,如byte, int, long, float, double等,包含对应的类型的数组,如In...原创 2018-12-30 23:25:37 · 3813 阅读 · 0 评论 -
Java DTO(data transfer object)的使用
解耦接口调用者与接口实现者:在接口设计当中,如果涉及到同时返回多个关联对象,如问题Question,又包括问题选项QuestionOptions,此时一般想到的做法是使用一个Map,然后将qustion和questionOption分别作为key,然后返回,这种做法使得调用者需要查看接口实现代码,才能明确知道这个map里面放了什么东西,造成接口调用者与接口实现者紧密耦合,故可以设计一个新的DTO...原创 2018-11-12 14:25:08 · 4268 阅读 · 0 评论