首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

java解惑(Map的施用,静态导入方法,线程中断interrupted与线程死锁)

2012-10-31 
java解惑(Map的使用,静态导入方法,线程中断interrupted与线程死锁)Map的使用注意:IdentityHashMap此类利用

java解惑(Map的使用,静态导入方法,线程中断interrupted与线程死锁)
Map的使用



注意:
IdentityHashMap此类利用哈希表实现 Map 接口,比较键(和值)时使用引用相等性代替对象相等性。换句话说,在 IdentityHashMap 中,当且仅当 (k1==k2) 时,才认为两个键 k1 和 k2 相等
2,静态导入方法


Thread.interrupted()为Thread的静态方法,调用它首先会返回当前线程的中断状态(如果当前线程上调用了interrupt()方法,则返回true,否则为false),然后再清除当前线程的中断状态,即将中断状态设置为false。换句话说,如果连续两次调用该方法,则第二次调用将返回 false。而isInterrupted()方法为实例方法,测试线程是否已经中断,并不会清除当前线程中断状态。
所以这里应该使用isInterrupted()实例方法,就可以修复该问题。

线程问题
package other;//类的初始化,先初始化静态域,静态块,public class Lazy {private static boolean initial = false;static {Thread t = new Thread(new Runnable() {public void run() {System.out.println("befor...");//此句会输出/* * 由于使用Lazy.initial静态成员,又因为Lazy还未 初 * 始化完成,所以该线程会在这里等待主线程初始化完成 */initial = true;System.out.println("after...");//此句不会输出}});t.start();try {t.join();// 主线程等待t线程结束} catch (InterruptedException e) {e.printStackTrace();}}//staticpublic static void main(String[] args) {System.out.println(initial);}}

执行结果就是:befor...

当一个线程访问一个类的某个成员的时候,它会去检查这个类是否已经被初始化,在这一过程中会有以下四种情况:
1、这个类尚未被初始化
2、这个类正在被当前线程初始化:这是对初始化的递归请求,会直接忽略掉(另,请参考《构造器中静态常量的引用问题》一节)
3、这个类正在被其他线程而不是当前线程初始化:需等待其他线程初始化完成再使用类的Class对象,而不会两个线程都会去初始化一遍(如果这样,那不类会初始化两遍,这显示不合理)
4、这个类已经被初始化
当主线程调用Lazy.main,它会检查Lazy类是否已经被初始化。此时它并没有被初始化(情况1),所以主线程会记录下当前正在进行的初始化,并开始对这个类进行初始化。这个过程是:主线程会将initial的值设为false,然后在静态块中创建并启动一个初始化initial的线程t,该线程的run方法会将initial设为true,然后主线程会等待t线程执行完毕,此时,问题就来了。
由于t线程将Lazy.initial设为true之前,它也会去检查Lazy类是否已经被初始化。这时,这个类正在被另外一个线程(main线程)进行初始化(情况3)。在这种情况下,当前线程,也就是t线程,会等待Class对象直到初始化完成,可惜的是,那个正在进行初始化工作的main线程,也正在等待t线程的运行结束。因为这两个线程现在正相互等待,形成了死锁

热点排行