0%

这一章主要讲述线程的发展历史,以及并发编程带来的优势和挑战。1946年第一台计算机诞生,一直到20世纪50年代中期,这时候的计算机没有操作系统的概念,采用手工操作的方式工作,每次只能有一个人使用计算机。此时的手工操作方式,用户独占全机,昂贵的计算机资源得不到充分利用。后来,随着计算机的发展,出现了批处理系统、多道程序系统,它们都提升了计算机的资源利用率。1961年,分时系统(Time Sharing System)出现,此时的一台计算机可以供多个用户终端同时连接并使用,就好像自己在独占计算机一样。分时系统将CPU的运行时间分成很短的时间片,按时间片分配给不同的连接终端使用,这充分利用了计算机资源,看起来就好像多个用户在同时使用计算机一样。
阅读全文 »

《Java并发编程实战》是 Brian Goetz 等 6 位 Java 大师合著的介绍 Java 并发编程的经典著作,这部名著由浅入深的介绍了 Java 并发编程的诸多知识,是一本完美的Java并发参考手册,豆瓣评分 9.0,可见其受欢迎程度。《Java并发编程实战》从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程安全类组合成更大的线程安全类,如何利用线程来提高并发应用程序的吞吐量,如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。
阅读全文 »

死锁是多线程编程中最常见的一种"活跃性问题",除了死锁还包括"饥饿"和"活锁",这些活跃性问题给并发编程带来极大的挑战。比如出现死锁时,定位和分析问题相对困难,一旦出现死锁,通常只能重启应用程序。本文通过死锁最经典的"哲学家就餐问题"来介绍死锁的产生原因和解决办法。死锁指的是多个线程相互等待彼此而进入永久暂停状态。比如,线程 T1 持有锁 L1 去申请锁 L2,但是线程 T2 持有锁 L2 申请锁 L1,此时它们都在等待对象释放锁,从而进入永久阻塞状态。这就好比两个小朋友,他们各有一个玩具,但都不愿意分享给对方,却希望获得对方的玩具,最终互不相让,只能彼此干瞪眼了。
阅读全文 »

您有没有遇到各种需要走流程的事情?比如,请假申请,假设公司规定,3天以内的请假申请组长可以直接审批,而4到7天的请假申请必须要让部门经理来审批了,超过7天的请假申请只能由公司总经理来审批。类似的场景还有很多,尤其在工作流中,比如物资审批、报账审批、资金审批等等……
阅读全文 »

中国有句古话:"千金难买后悔药"。生活中很多时候,我们做过了的事情,虽然后悔,却无济于事。但是,在软件世界,我们却可以自己制作"后悔药"。比如,以前玩"仙剑",每每遇到Boss战,那必须要存档的,就算没打过也可以恢复存档再来一次,否则,玩过的人都知道,哭去吧……这里的游戏存档,就会用到今天说的——备忘录模式。
阅读全文 »

生活中,存在这样的场景:需要逐个遍历一堆对象,然后判断对象是否符合要求,做出相应的处理。例如,乘火车时,检票员站在门口挨个检票,没有买票的人不能乘车。类似的场景还有很多,比如乘地铁、乘公交、从书架上找书、食堂排队打饭等等…… 我们把需要逐个遍历的这一堆对象称为对象集合,把挨个遍历的过程称为迭代。迭代时,如果能将迭代过程从对象集合中抽取出来单独实现,让对象集合只负责管理自身状态,而不用负担迭代的任务,这就减轻了对象集合的职责,这就是今天要说的——迭代器模式。
阅读全文 »

如果您有租房的经历,那么您对中介并不陌生。租房时,我们先去房屋租赁中介登记,告诉它您的租房需求,然后中介会按照您的要求为您筛选适合的房子。房子确定后,您会与中介签订租赁合同,缴纳费用,然后拿到钥匙……整个过程中,所有事项都由中介一手包办,入住以后房屋有任何问题,您都直接去找中介,您甚至可能并不知道房东是谁。这就是我们今天要说的模式——中介者模式。
阅读全文 »

很快又到年底了,一年一度的春节除了可以享受愉快地享受假期之外,每年的"春节联欢晚会"也是让人倍感期待。然而,大多数人都没能坐在电视机跟前等着它的开始,有的人在厨房忙着准备丰富的食物,有的在一起打麻将、玩牌,还有的可能在玩电脑游戏……大家都想看晚会,于是派出一个小朋友,告诉他:"如果晚会开始了,你要立刻来通知我们哦!"虽然,大家就可以继续做自己的事情,小朋友就坐在电视跟前,当晚会开始的时候,他就立即跑去挨个通知大家……
阅读全文 »

2021年又过去了,不得不让人感叹岁月如梭、光阴似箭!正值元旦假期,刚好有时间梳理一下这过去一年的种种,思来想去,还是不过"平凡"二字罢了。每年的年底,我都会做一下年终总结,也定制一下新的一年的计划。现在回过头去看,发现去年的计划完成度也只有40%,很多事情还是没有能够完成。一方面,计划可能定得过高,完成起来有一定的难度;另一方面,自身的自制力还有待提高,很多事情没有能够坚持去完成;再者,诸如读书这样的事情,如果阅读了但是没有去理解、梳理和总结,还是很难形成系统的经久不忘的知识。
阅读全文 »

最近在维护一个老项目的时候,看到一段密码匹配的代码,感觉很奇怪,于是遍寻资料,最终还是很有收获。在密码学中,时序攻击是一种侧信道攻击,攻击者试图通过分析加密算法的时间执行来推导出密码。每一个逻辑运算在计算机需要时间来执行,根据输入不同,精确测量执行时间,根据执行时间反推出密码。
阅读全文 »

JDK1.8注解可以标注在任何类型上,获取注解的方式也随之扩展了。AnnotatedType 接口的目的在于获取泛型类型上的注解,包括泛型参数、通配符、上下边界等,前提是目标元素声明了泛型类型并且标注了注解,否则其 getType 方法将返回原始类型。
阅读全文 »

AnnotatedElement接口是用于反射获取注解的顶层接口,其api获取的注解与注解的存在形式息息相关,注解有四中存在形式:直接存在、间接存在、存在和关联。这几种注解存在的形式的出现原因,一方面是由于注解可以通过继承关系传递,另一方面是Java提供了定义可重复注解的功能。
阅读全文 »

很多时候,我们需要获取到泛型类上定义的具体类型,从而完成一些业务逻辑。比如,最常见的情景就是JSON的反序列化,需要将JSON字符串反序列化为泛型的具体类型,比如反序列化为 `List`,这就要求每一个 `List` 中的元素都是 `User` 对象。那么,如何获取到泛型类上定义的具体类型呢?这就是本文要阐述的内容。
阅读全文 »

Type接口是JDK1.5新增的表示Java所有类型的接口,它有5个组件,除了Java的类、接口的原始类型可以用Class来描述,其他的几个组件都是用来描述泛型类型的,分别是描述整个泛型的ParameterizedType、描述泛型类型变量的TypeVariable、描述泛型通配符的WildcardType,以及描述泛型数组的GenericArrayType。
阅读全文 »

泛型是编译期特性,我们能否创建泛型数组呢?通过 `Array` 类,除了可以动态的获取和设置数组的元素,还可以动态创建类型安全的数组。
阅读全文 »

反射是JDK5推出的非常重要的特性,通过反射,开发者可以在运行时动态的创建类实例,获取、更改、调用类的相关信息、方法等。反射也是各大框架使用的主要技术,如知名的Spring framework框架。
阅读全文 »

MindManger是Mindjet公司开发一款思维导图软件,目前已经更新到了2021版本。与其他几大思维导图软件相比,个人最钟爱MindManger,因为他功能更强大、界面更友好,支持强大的备注体系,插图片、查表格都可以,可以直接用来做知识体系整理,非常方便。
阅读全文 »

状态模式建议为对象的所有可能状态新建一个类, 然后将所有状态的对应行为抽取到这些类中。当控制一个对象的状态转换条件过于复杂时,就可以将判断逻辑转移到状态类中,以简化复杂的判断逻辑。
阅读全文 »

你的J2EE项目是否耗费了你太多的时间?它们是否难以调试?它们是否效率不彰?也许你还在使用传统的J2EE方案,然而这种主案太过复杂,而且并非真正面向对象。这里的很多问题都与EJB有关:EJB是一种复杂的技术,但它没有兑现自己曾经的承诺。
阅读全文 »

命令模式的定义:将一个请求封装为一个对象,从而可以用不同的请求对客户进行参数化,并且可以对请求排队或记录日志,还支持可以撤销的操作。
阅读全文 »