当程序使用某个类时, 如果该类还没被初始化, 加载到内存中, 则系统会通过加载、连接、初始化三个过程来对该类进行初始化. 该过程就被称为类的初始化
在构造函数内对一个final域的写入, 与随后把这个被构造对象的引用赋值给一个引用变量, 这两个操作之间不能重排序.
初次读一个包含final域的对象的引用, 与随后初次读这个final域, 这两个操作之间不能重排序.
在构造函数内对一个final域的写入, 与随后把这个被构造对象的引用赋值给一个引用变量, 这两个操作之间不能重排序.
初次读一个包含final域的对象的引用, 与随后初次读这个final域, 这两个操作之间不能重排序.
锁是java并发编程中最重要的同步机制. 锁除了让临界区互斥执行外, 还可以让释放锁的线程向获取同一个锁的线程发送消息. 下面是锁释放-获取的示例代码:
当我们声明共享变量为volatile后, 对这个变量的读/写将会很特别. 理解volatile特性的一个好方法是: 把对volatile变量的单个读/写, 看成是使用同一个锁对这些单个读/写操作做了同步
如果程序是正确同步的, 程序的执行将具有顺序一致性(sequentially consistent)–即程序的执行结果与该程序在顺序一致性内存模型中的执行结果相同(马上我们将会看到, 这对于程序员来说是一个极强的保证). 这里的同步是指广义上的同步, 包括对常用同步原语(lock, volatile和final)的正确使用.
Java编译器、运行时会对指令进行重排序. 这种重排序在单线程和多线程情况下分别有什么影响呢?
介绍 Java 内存模型 3 大核心
写Java程序时会经常从classpath下读取文件, 是时候该整理一下了, 并在不断深入的过程中, 陆续补充上.
使用线程池主要为了解决一下几个问题:
生产者消费者问题是研究多线程程序时绕不开的经典问题之一, 它描述是有一块缓冲区作为仓库, 生产者可以将产品放入仓库, 消费者则可以从仓库中取走产品
Try-with-resources 是 java7 中一个新的异常处理机制, 它能够很容易地关闭在 try-catch 语句块中使用的资源
Web服务器一旦发出响应,一个请求响应过程就结束了. 当再次发出请求时,Web服务器不记得曾就做过的请求,也不记得给用户发出过响应.,这就是http的无状态模式
泛型, 即 “参数化类型”. 一提到参数, 最熟悉的就是定义方法时有形参, 然后调用此方法时传递实参. 那么参数化类型怎么理解呢?顾名思义, 就是将类型由原来的具体的类型参数化, 类似于方法中的变量参数, 此时类型也定义成参数形式(可以称之为类型形参), 然后在使用 / 调用时传入具体的类型(类型实参)
泛型, 即 “参数化类型”. 一提到参数, 最熟悉的就是定义方法时有形参, 然后调用此方法时传递实参. 那么参数化类型怎么理解呢?顾名思义, 就是将类型由原来的具体的类型参数化, 类似于方法中的变量参数, 此时类型也定义成参数形式(可以称之为类型形参), 然后在使用 / 调用时传入具体的类型(类型实参)
JUnit 是一个开放源代码的 Java 测试框架, 用于编写和运行可重复的测试. 他是用于单元测试框架体系xUnit的一个实例(用于java语言).
代码优化, 一个很重要的课题. 可能有些人觉得没用, 一些细小的地方有什么好修改的, 改与不改对于代码的运行效率有什么影响呢? 这个问题我是这么考虑的, 就像大海里面的鲸鱼一样, 它吃一条小虾米有用吗?没用, 但是, 吃的小虾米一多之后, 鲸鱼就被喂饱了. 代码优化也是一样, 如果项目着眼于尽快无BUG上线, 那么此时可以抓大放小, 代码的细节可以不精打细磨. 如果有足够的时间开发、维护代码, 这时候就必须考虑每个可以优化的细节了, 一个一个细小的优化点累积起来, 对于代码的运行效率绝对是有提升的.
方法区是 JVM 的规范, 永久代(PermGen space)是 HotSpot 对这种规范的实现, 在 JDK 1.8 中, HotSpot 已经没有 PermGen space
这个区间了, 取而代之的是 Metaspace(元空间).