1,自旋锁
2,阻塞锁,被阻塞的线程,不会去争夺锁
3,可重入锁(ReentrantLock)
4,读写锁(ReadWriteLock)
5,互斥锁
6,悲观锁,不相信这里是安全的,必须上锁
7,乐观锁,相信这里是安全的
8,公平锁, 有优先级的锁
9,非公平所, 无优先级的锁
10,偏向锁,无竞争不锁,有竞争挂起,转为轻量锁
11,对象锁, 锁住对象
12,线程锁
13,锁粗化,多个锁变成一个锁,jvm自己处理
14,轻量级锁,CAS实现
15,锁消除,偏向锁就是锁消除的一种
16,锁膨胀,轻量级锁失效,则膨胀为重量级锁
17,信号量
18,排它锁,X锁,某对数据对象上锁,则其他事务对象不能对次数据对象上锁
throws用在方法上
throw用于抛出异常
finally如果在try或者catch中遇到jvm系统退出语句,如System.exit(0),也不会执行finally中的语句
boolean[]默认值为false
float[],double[],默认值为0.0
对象类型数组:
默认值为null
新生代和老年代, 新生代==eden + 2 * survivor
老年代==old
方法区不属于堆, 运行时常量池位于方法区中
简言之:就是把目标方法的代码复制到发起调用的方法之中,避免发生真是的方法调用,是编译器最重要的优化手段之一,除了消除方法调用的成本之外,他更重要的意义是为其他优化手段建立良好的基础
java中,只有使用invokespecial指令代用的private方法,实例构造器,父类放方法以及使用invokestatic修饰的静态方法才是在编译期中进行解析的,除了以上几种方法(也不包括final方法)外,都是需要运行期进行多态选择
简言之, 除了private方法,实例构造器,父类放方法以及使用invokestatic修饰的静态方法外,只有使用final修饰方法,才会进行方法内联,将一个方法声明为内联函数(但是还要再看jvm怎么判断,由jvm决定方法内联)
如果方法体比较大,进行内联展开就会有比较大的时间空间开销
如果函数体含有递归,在某些编译器中会造成编译器的无穷编译
但是C选项,如果换成char a = 1/3 ; 那么也是正确的, 会将a变为0所对应的char值
java中,数组是一种由jvm自动生成的对象,直接继承与Object,创建动作由newarray触发
因为数组是对象,所以数组位于堆中
1,父类静态属性,静态代码块
2,子类静态属性,静态代码块
3,父类普通属性,代码块
4,父类构造方法
5,子类普通属性,代码块
6,子类构造方法
ParNew 1.4
Parallel Scavenge 1.4
CMS 1.5
Serial Old 1.5
Parallel old 1.6
G1 1.7
1,通过一个类的全限定名获取定义此类的二进制字节流
2,将这个字节流所代表的静态存储结构转为方法区的运行时数据结构
3,在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的方法入口
在类的解析阶段,会进行:
1,类或者接口的解析
2,字段解析
3,类方法解析
4,接口方法解析
在类的初始化阶段,会进行 :
在准备阶段,变量已经赋值过一次系统要求的初始值, 在初始化阶段,根据程序员通过程序制定的主观计划去初始化类变量:初始化阶段就是执行类构造器 clinit 的过程
clinit是编译器自动收集类中所有类变量的赋值动作he静态语句块中的语句合并产生的
ini类型的对象成员变量,不属于类变量,那么肯定在实例化对象后才有。在类加载的时候会赋予初值的是类变量,而非对象成员变量。
抽象类中,可以有静态属性,静态方法,普通属性,普通方法,可以没有abstract方法
接口中,只能有抽象方法+普通静态方法,接口中的方法,不管是不是默认,都只能被public修饰,不能用protected修饰,也不能用default修饰,接口中,不能有非静态的普通方法,只能有静态方法
但是,每一个线程里面,三个add和printAll的执行顺序是不变的,也就说, 一定有连续的A,B,C,A,B,C,A,B,C 对于A,B,C,A,B,C,A,B,C,就是顺序执行的结果
对于E,就是在执行了线程1的三个add,在执行线程1的printAll之前,执行了线程2 的add("A"),这样,线程1的printAll方法就会打印出ABCA,然后在执行线程2的add("B"),add("C"),这样,线程2的printAll方法就会打印出ABCABC