《Java编程思想》中关于线程的描述
最开始,线程只是用于分配单个处理器的处理时间的一种工具。但假如操作系统本身支持多个处理器,那么每个线程都可分配给一个不同的处理器,真正进入“并行运算”状态。从程序设计语言的角度看,多线程操作最有价值的特性之一就是程序员不必关心到底使用了多少个处理器。程序在逻辑意义上被分割为数个线程;假如机器本身安装了多个处理器,那么程序会运行得更快,毋需作出任何特殊的调校。
利用对象,可将一个程序分割成相互独立的区域。我们通常也需要将一个程序转换成多个独立运行的子任务。象这样的每个子任务都叫作一个“线程”(Thread)。编写程序时,可将每个线程都想象成独立运行,而且都有自己的专用CPU。一些基础机制实际会
2018-05-14
java并发
数组实现的优先队列
MyLoopQueue
package DataStructure;
import java.util.NoSuchElementException;
/**
* 这是一个用数组实现的优先队列。
*
* 该思路参考《数据结构Java语言描述》的page249。
*
* 入队时通过指定优先级参数添加到优先队列,出队时,不同优先级之间优先级较高的先出队,
* 相同优先级,先入先出。
*
* 内部维护了一个队列数组,靠队列数组来简单地实现不同优先级队列的读写
* 当初始化时指定一个最高优先级,然后用for循环一次性把数组中的对象都new出来。
* add方法额外传入一个int
2018-04-28
算法
数组实现固定长度的循环队列
只要指定了初始大小之后就都还能用,后进后出,就是不能动态扩容,也不能指定了一次容量之后再变更容量,由于水平原因,在尝试复制数组的时候因为头指针和尾指针不知道如何处理,没能实现循环队列的动态扩容功能。而官方的ArrayDeque是动态扩容的双端队列,可以去看那个的实现方法。
package DataStructure;
import java.util.NoSuchElementException;
public class MyLoopQueue<T> {
private T[] array;
private int front;
private in
2018-04-27
算法
java对象的创建、内存布局、对象访问
对象的创建:
检查被new的对象的类是否已经被加载,解析,初始化过。若没有,执行相应的类加载过程
分配内存(两种方式) 1. 指针碰撞:用Serial、ParNew等带Compact过程的垃圾收集器
2. 空闲列表:用CMS这种基于Mark-Sweep算法的垃圾收集器。
内存分配不是线程安全的:在并发情况下,可能出现在给对象A分配内存,指针还没来得及修改,对象B又使用了原来的指针来分配内存。解决方法:
对分配内存空间的动作进行同步处理:用CAS配上失败重试。
把内存分配的动作按照不同线程分配到不同空间中进行:每个线程在堆中预先分配一小块本地线程分配缓冲(TLAB),哪个线程
2018-04-22
JVM
java运行时数据区
读《深入理解Java虚拟机》读书笔记
程序计数器:
为了保证程序能够连续地执行下去,处理器必须具有某些手段来确定下一条指令的地址,而程序计数器正是起到这种作用。
用来记录当前线程所执行的字节码的行号。字节码解释器的工作就是通过改变程序计数器来选取下一条需要执行的字节码指令(分支,循环,跳转,异常,线程恢复等)。
JVM的多线程是通过线程轮流切换并分配处理器执行时间来实现的。在一个确定时刻,一个处理器都只会执行一条线程中的指令。因此为了线程切换后能恢复到正确执行位置,每条线程需要一个独立的程序计数器,各条线程之间计数器互不影响,独立存储。因此程序计数器的内存区域是线程私有的内存。
Java虚拟
2018-04-22
JVM
Java虚拟机是什么?
一句话解释:它是一种基于下层的操作系统和硬件平台并利用软件方法来实现的抽象的计算机,可以在上面执行java的字节码程序。
JVM是Java程序运行的容器,但是他同时也是操作系统的一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间。
JVM在整个jdk中处于最底层,负责与操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,因此也叫虚拟计算机。
如果把Java原程序想象成我们的C++原程序,Java原程序编译后生成的字节码就相当于C++原程序编译后的80x86的机器码(二进制程序文件),JVM虚拟机相当于80x86计算机系统,Java解释器相当于80x86CPU
2018-04-22
JVM