Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bruce Eckel ThinkingIn Java第4版,ThreadLocalVariableHolder_Java_Multithreading - Fatal编程技术网

Bruce Eckel ThinkingIn Java第4版,ThreadLocalVariableHolder

Bruce Eckel ThinkingIn Java第4版,ThreadLocalVariableHolder,java,multithreading,Java,Multithreading,书中的两个片段(并发章节): 类访问器实现可运行{ 私有最终int id; 公共访问器(int idn){ id=idn; } 公开募捐{ 而(!Thread.currentThread().isInterrupted()){ ThreadLocalVariableHolder.increment(); System.out.println(本文件); 螺纹屈服强度(); } } 公共字符串toString(){ 返回“#”+id+”:“+ ThreadLocalVariableHolder.g

书中的两个片段(并发章节):

类访问器实现可运行{
私有最终int id;
公共访问器(int idn){
id=idn;
}
公开募捐{
而(!Thread.currentThread().isInterrupted()){
ThreadLocalVariableHolder.increment();
System.out.println(本文件);
螺纹屈服强度();
}
}
公共字符串toString(){
返回“#”+id+”:“+
ThreadLocalVariableHolder.get();
}
}
公共类ThreadLocalVariableHolder{
私有静态线程本地值=
新ThreadLocal()/*{
私人随机兰德=新随机兰德(47);
受保护的同步整数初始值(){
返回耐克斯汀兰特(10000);
}
};*/
公共静态无效增量(){
value.set(value.get()+1);
}
公共静态int get(){
返回值。get();
}
公共静态void main(字符串[]args)引发异常{
ExecutorService exec=Executors.newCachedThreadPool();
对于(int i=0;i<5;i++)
exec.execute(新访问器(i));
TimeUnit.SECONDS.sleep(3);//运行一会儿
exec.shutdownNow();
//所有访问者都将退出
}
}

类中的ThreadLocalVariableHolder是内部类ThreadLocal,其方法initialValue和属性rand未显式使用。若我评论整个课程的内容(就像我在这里所做的),它仍然会产生类似的结果。我想,这段代码已经过时了。你知道吗,为什么这段代码在内部类中,目的是什么吗?

我怀疑,如果我运行你的代码,它会将NPE抛出
increment()->value.get()

这是有效的,因为
ThreadLocal
中的默认实现将返回
null

protected T initialValue() {
        return null;
    }
JavaDoc

返回此线程局部变量的当前线程“初始值”。当线程第一次使用get方法访问变量时,将调用此方法,除非线程先前调用了set方法,在这种情况下,不会为线程调用initialValue方法。通常,每个线程最多调用一次此方法,但在随后调用remove和get时,可能会再次调用此方法

此实现仅返回null;如果程序员希望线程局部变量的初始值不是null,则必须对ThreadLocal进行子类化,并重写此方法。通常,将使用匿名内部类


因为这个示例的行为是strength,所以我不会删除这个错误的代码。复制它。在内部类中取消注释注释行,编译它,然后返回注释并重试。我必须转到构建部分并删除.class文件以获得NullPointerException。可在NetBeans 8.0、JDK 1.7上复制。它可能被报告为与内部类绑定的bug

为了解释这个例子。ThreadLocal类是java.lang中的prepared类,它有一些不常见的特殊功能:

此类提供线程局部变量。这些变量不同 与它们的正常对应线程相比,每个访问一个线程的线程 (通过其get或set方法)有自己的独立初始化 变量的副本。ThreadLocal实例通常是私有的 希望将状态与线程关联的类中的静态字段 (例如,用户ID或交易ID)


我必须说,编写自己的类要比理解ThreadLocal类在做什么容易,即使或者仅仅因为原始解决方案更简洁。

是的,我将相同的代码完全复制到一个新的简单项目中。然后,它会按预期发出NullPointerException。问题不在示例中,而是在另一点上。已解决。已解决,示例按预期工作。
protected T initialValue() {
        return null;
    }