您的位置:首页 > 编程语言 > Java开发

Java基础知识大整理

2014-10-23 09:42 288 查看
Java并发包
锁机制:通过cas机制保证了当多线程并发时,就算所有的线程都同时访问,但是只会有一个成功,而锁的本质就是,只有一个能操作其他的都“睡觉”,当使用lock是,一定要注意lock与unlock的次数要相等

volatile机制:参考下面的例子,也就是说对volatile修饰的变量的修改不能依赖于当前的值,所以感觉volatile只能使用在标志位了

<span style="font-size:18px;">public class VolatileTest {
public static volatile int i;

public VolatileTest();
Code:
0: aload_0
1: invokespecial #1                  // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0

public static void increase();
Code:
0: getstatic     #2                  // Field i:I, 把i的值取到了操作栈顶,volatile保证了i值此时是正确的.
3: iconst_1
4: iadd                              // increase,但其他线程此时可能已经把i值加大了好多
5: putstatic     #2                  // Field i:I ,把这个已经out of date的i值同步回主内存中,i值被破坏了.
8: return
LineNumberTable:
line 6: 0
line 7: 8
}</span>


原子变量:也是通过cas机制实现的,cas是什么:compare and swap就是线比较在修改

Thread

ThreadLocal:线程本地变量,或者说是线程的私有变量,这不是解决线程安全问题的解决方法,可以当作一个传值工具,但不建议这么做

public class ThreadLocalTest {

static class ResourceClass {

public final static ThreadLocal<String> RESOURCE_1 = new ThreadLocal<String>();

public final static ThreadLocal<String> RESOURCE_2 = new ThreadLocal<String>();

}

static class A {

public void setOne(String value) {
ResourceClass.RESOURCE_1.set(value);
}

public void setTwo(String value) {
ResourceClass.RESOURCE_2.set(value);
}
}

static class B {
public void display() {
System.out.println(ResourceClass.RESOURCE_1.get() + ":" + ResourceClass.RESOURCE_2.get());
}
}

public static void main(String []args) {
final A a = new A();
final B b = new B();
for(int i = 0 ; i < 15 ; i ++) {
final String resouce1 = "线程-" + i, resouce2 = " value = (" + i + ")";
new Thread() {
public void run() {
try {
a.setOne(resouce1);
a.setTwo(resouce2);
b.display();
}finally {
ResourceClass.RESOURCE_1.remove();
ResourceClass.RESOURCE_2.remove();
}
}
}.start();
}
}
}
与此相对应的,就得说说unsafe类,在并发包的lock中的AQS就是使用的这个来使Thread挂起的

Java对象初始化

Java中的初始化顺序

对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是

(静态变量、静态初始化块)>(变量、初始化块)> 构造器。

JAVA类首次装入时,会对静态成员变量或方法进行一次初始化,但方法不被调用是不会执行的,静态成员变量和静态初始化块级别相同,非静态成员变量和非静态初始化块级别相同。

初始化顺序:先初始化父类的静态代码--->初始化子类的静态代码-->

(创建实例时,如果不创建实例,则后面的不执行)初始化父类的非静态代码(变量定义等)--->初始化父类构造函数--->初始化子类非静态代码(变量定义等)--->初始化子类构造函数

类只有在使用New调用创建的时候才会被JAVA类装载器装入创建类实例时,首先按照父子继承关系进行初始化类实例创建时候,首先初始化块部分先执行,然后是构造方法;然后从本类继承的子类的初始化块执行,最后是子类的构造方法类消除时候,首先消除子类部分,再消除父类部分.



运行以上代码,我们会得到如下的输出结果:
静态变量
静态初始化块
变量
初始化块
构造器





运行一下上面的代码:
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
说明:并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。



运行上面的代码,会得到如下的结果:
Test--A
静态初始化块
Test--B
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: