`
文章列表
前言   在上一篇《java中的线程安全》中,总结了什么是线程安全,并在文章末尾提到如何保证线程安全的几种常用手段,并且重点说明了为了保证线程安全一般都会付出一定代价。   比如使用线程安全的容器ConcurrentHashMap,本质上还是会有分段锁;使用volatile保证可见性,同样会有性能消耗:线程中无法使用缓存数据每次都必须从主存中获取;使用原子工具包中的AtomicInteger,本质上还是通过CAS和volatile,同样存在性能消耗;加锁方式就不说了,性能消耗是最大的。   上面提到的性能消耗,其实是在不需要保证线程安全的情况下对比的。也就是说在多线程环境下,如果 ...
前言   在程序设计中有一种常用的提升数据查询性能的手段以--空间换时间。典型的场景就是使用“缓存”,在查询数据库之前加一层“全局共享缓存”(如:redis),更有甚者在应用实例内部在加一层“本地缓存”。以java应用+mysql数据库为例,该架构设计方式如下:     数据查询逻辑为:       本地缓存的查询速度是纳秒级
前言   前面讲过使用synchronized关键字来解决“线程安全”问题,其本质是将“并行”执行改“串行”,也就是所谓的“同步”,前面也讲过这种方式的代价较高。在java中还提供一种弱化版的同步机制:volatile变量。   为什么说是弱化版的同步机制呢?首先看下在使用synchronized关键字保证的 (强)同步机制的三个特性说起:原子性、可见性、有序性,也就是说使用synchronized加锁可以同时保证程序执行过程中的原子性、可见性、有序性。   1、原子性:   这个特性更事务处理中的原生性有点类似:单个或多个操作是作为整体一起执行,要么全部执行,要么都不执行。 ...
现有案例分析   系统融合,简单的说就是把多个系统合并成一个系统。组件化,是在服务化的拆分基础上,提取可独立部署和多次服用的部分。一个是合并,一个拆分,看似矛盾,但两者却可以同时使用,相得益彰。   笔者 ...
理解队列和消息队列   队列(来自百度百科):是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。   消息队列(来自百度百科):是在消息的传输过程中保存消息的容器。   从队列和消息队列的定义看来,看不出什么相似之处。但我理解它们的作用是相似的,只是使用环境不同。队列和消息队列 本质上都可以用于解决“生产者”和“消费者”问题,在二者这间建立桥梁,it中专业术语是对“生产者”和“消费者”进行解耦。可以动态的通过调整
什么是线程安全   线程安全问题在各种编程语言中都存在,需要首先申明的是:本文做所指的线程安全都是基于java语言展开讨论的。在定义“什么是线程安全”之前,首先来看下进程、线程和多线程。   进程:(百度百科 ...
聚合类型兼容性问题   接上一次分享《系统融合 -- 适配器模式》,在对A、B两个系统进行融合的过程中,可以使用“适配器模式”把两类业务类似但接口定义不同的接口适配为同一个系统。在两个系统融合过程中,还经常遇 ...
搜索框的附加功能   在日常的web开发中,经常有搜索框功--在一批数据中检索自己需要的数据。现在的百度以及各大电商的搜索框都做得很人性化,主要体现在两个方面:   一、搜索框的“搜索历史”:为了方便用户下次搜 ...
关于状态的案例   在日常开发中经常会遇到 一个对象有多种状态的情形,并且在不同的状态下需要执行的动作会不同。很多朋友一般会采用if elseif else语句进行判断不同的状态,对匹配到的不同状态进行不同的业务逻辑处理。这样所有的业务逻辑代码都被融合在一起,不符合“开闭原则”验重影响代码的可读性,以及将来代码的维护(比如新增状态)。   下面来看一个笔者遇到的真实案例,在设计一个“页面浏览”的web服务技术架构实现时,由于页面渲染时间较长,为了防止高并发情况下的阻塞,采用了页面异步渲染的方式:每次页面请求都从redis缓存中获取已渲染好的页面内容返回,如果缓存状态过期时,只允许发起一 ...
java.io包的困惑   对于初识java的程序员来说,甚至已经工作三五年的java老鸟们,对java.io包中各种“流”以及五花八门的api都是浑浑噩噩搞不清(笔者在刚接触java时也经历过同样的迷茫)。但如果你已经熟悉了“装饰器模式”的话,再来看一遍java.io中API,就会有一种豁然开朗的感觉。   继承是实现类复用的重要手段,但却不是唯一的手段,通过类的关联组合同样可以做到,而且如果使用得当 比通过继承更富有弹性。“装饰器模式”就是通过组合来实现类似复用和包装,这就是OO设计的另一个原则“合成复用原则”:则是尽量使用合成/聚合的方式,而不是使用继承。   在讲解jav ...
什么是复杂对象   所谓复杂对象,指的是对象的成员变量是由一系列的其他对象组成,其中每对象的创建和赋值都是单独的业务逻辑。如果把这个复杂对象称为一个产品,那组成的这个对象的一系列其他对象称为“产品簇”。 ...
魔兽世界中的命令场景   笔者以前是个普通的魔兽世界玩家,每个魔兽世界玩家心中都比别人多一个世界。但同时笔者是一名程序员,经常又会在程序员的世界去思考游戏中各种场景是怎么实现的。今天心血来潮,准备使用“命令模式”为魔兽世界设计一套“技能释放”系统,包括:命令设计、宏命令、游戏外挂等具体实现过程。   在讲解命令模式之前,首先让我们来回味下魔兽世界中法师职业的技能:寒冰箭、火球术、奥术强化、气定神闲 等等,由于技能太多这里只列出4个技能。这些技能与普通游戏没什么两样,但魔兽世界的强大之处在于 可以让玩家根据自己的按键习惯,随意设置技能释放的快捷键。比如我个人的设置:数字键1--寒冰箭、 ...
什么是系统融合   何谓系统融合,简单的说就是把两个或者多个系统融合为一个系统。在一个公司中,为了降低维护成本,会遇到将两个或者多个业务类似的系统融合成一个系统的场景。有人会问为什么同一个公司会有多个 ...
组合模式介绍   组合模式 主要用于解决对象之间树形结构的父子关系,典型的运用场景有:网页上的菜单管理(多级菜单);以及父子结构的xml文件解析等(比如Dom4J)。组合模式一般会结合“迭代器模式”一起使用,解决 ...
遇到的问题   在使用redis的过程中,尤其是在做大数据“实时计算”的过程中,也许会经常遇到下列场景:比如网站每个页面的实时pv运算,使用storm(或者spark streaming)从kafka中消费实时点击流数据进行统计计算;并计算好的结果放入redis进行存储,如果redis中已经存在 需要先取出来与最新统计数据相加再放入redis;另外为了减少与redis的交互次数,降低redis的存取压力,一般不会消费一条数据后就立即放入redis,而是处理一批数据后再存入redis,大致流程如下:  
Global site tag (gtag.js) - Google Analytics