//this引用逃逸
// 1.构造器还未完成前,将自身this引用向外抛,使其他线程访问这个引用,进而访问到其未初始化的变量,造成问题
// 2.内部类访问外部类未初始化的成员变量
//3.多态继承中,父类访问子类未初始化的成员变量
public class TestThisEscape {
final int a;
int b = 3;
static TestThisEscape obj;
public TestThisEscape(){
a= 3;
b= 5;
//obj = new TestThisEscape(); //在构造器中很明显抛出引用会造成this引用逃逸
} public static void main(String[] args) {
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("---------------");
obj = new TestThisEscape();
System.out.println("============");
}
},"threadA"); Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
TestThisEscape obj1 = obj;//obj未初始化完成,this引用被使用造成空指针一场
// try {
System.out.println(obj1.a);
//} catch (Exception e) {
System.out.println(Thread.currentThread().getName()+" a变量未初始化");
//}
try {
System.out.println(obj1.b);
} catch (Exception e) {
System.out.println(Thread.currentThread().getName()+" b变量未初始化");
}
}
},"threadB");
threadA.start();
threadB.start();
} }

  

/**
* this逸出条件:1.构造函数中创建内部类。2.构造函数中将这个内部类的引用发布了出去
*/
public class TestInnerClassThisEscape {
final int a;
int b = 3;
String c;
static TestInnerClassThisEscape obj;
public TestInnerClassThisEscape(){
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(TestInnerClassThisEscape.this.a);
System.out.println(TestInnerClassThisEscape.this.b);
System.out.println(TestInnerClassThisEscape.this.c);
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
a= 3;
b= 5; } public static void main(String[] args) {
new TestInnerClassThisEscape();
} }
public class TestThisPC {
public static void main(String[] args) {
new Child();
}
}
class Parent{
Parent(){
print();
}
void print(){
System.out.println("----------");
}
} class Child extends Parent{
int a = 5;
void print(){
System.out.println("-----------"+ a);
}
Child(){
super();
print();
}
}

  

解决方案:
1.初始化在调用之前

this引用逃逸问题的更多相关文章

  1. this引用逃逸

    1.什么是This逃逸? 在构造器构造还未彻底完成前(即实例初始化阶段还未完成),将自身this引用向外抛出并被其他线程复制(访问)了该引用,可能会问到该还未被初始化的变量,甚至可能会造成更大严重的问 ...

  2. this引用逃逸(使用内部类获取未外部类未初始化完的变量),多态父类使用子类未初始化完的变量

    1,this引用逃逸 并发编程实践中,this引用逃逸("this"escape)是指对象还没有构造完成,它的this引用就被发布出去了. 这是危及到线程安全的,因为其他线程有可能 ...

  3. 你不知道的Java引用

    什么是引用   引用就是保存着一块地址(门牌号)的对象,就像C语言的指针那样,引用可以传递某个数据的地址,如果我们想拿到某一条数据,就要先找到他的地址,然后告诉计算机我去拿这个地址的数据,最后计算机就 ...

  4. 浅析java内存模型--JMM(Java Memory Model)

    在并发编程中,多个线程之间采取什么机制进行通信(信息交换),什么机制进行数据的同步? 在Java语言中,采用的是共享内存模型来实现多线程之间的信息交换和数据同步的. 线程之间通过共享程序公共的状态,通 ...

  5. java并发编程(十七)内存操作总结

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17377197 主内存与工作内存 Java内存模型的主要目标是定义程序中各个变量的访问规则, ...

  6. Java的线程安全

    线程安全 我们这里讨论的线程安全,就限定于多个线程之间存在共享数据访问这个前提,因为如果一段代码根本不会与其他线程共享数据,那么从线程安全的角度来看,程序是串行执行还是多线程执行对它来说是完全没有区别 ...

  7. java gc的工作原理、如何优化GC的性能、如何和GC进行有效的交互

    java gc的工作原理.如何优化GC的性能.如何和GC进行有效的交互 一个优秀的Java 程序员必须了解GC 的工作原理.如何优化GC的性能.如何和GC进行有效的交互,因为有一些应用程序对性能要求较 ...

  8. Java的内存模型

    "让计算机并发执行若干个运算任务"与"更充分地利用计算机处理器的效能"之间的因果关系,看起来顺理成章,实际上它们之间的关系并没有想象中的那么简单,其中一个重要的 ...

  9. 转《深入理解Java虚拟机》学习笔记之最后总结

    编译器 Java是编译型语言,按照编译的时期不同,编译器可分为: 前端编译器:其实叫编译器的前端更合适些,它把*.java文件转变成*.class文件,如Sun的Javac.Eclipse JDT中的 ...

随机推荐

  1. Cookie的实现

    Cookie是web server下发给浏览器的任意的一段文本,在后续的http 请求中,浏览器会将cookie带回给Web Server.同时在浏览器允许脚本执行的情况下,Cookie是可以被Jav ...

  2. IOS: Xcode报 Undecleared selector Warning错误的解决方法

    Undecleared selector  Warning 是编译器报的,特别是升级到IOS7 默认PROJ设定的时候,会出现这种问题,如果从代码上看语法完全没有问题,那么就可以在Xcode里面设置禁 ...

  3. charAt 写一个反序函数

    function reverStr(str){ var tmpStr = ""; for(var i=str.length-1;i>=0;i--){ tmpStr += st ...

  4. C#工具帮助类

    md5帮助类 .引入库 using System.Security.Cryptography;//引用Md5转换功能 .计算字符串的Md5值 public static string GetMD5Wi ...

  5. uvalive 3231

    3231 - Fair ShareAsia - Seoul - 2004/2005You are given N processors and M jobs to be processed. Two ...

  6. Redis防护建议

    1.Redis本身防护  (1)不要使用默认端口(6379)  (2)增加Redis用户名和密码  (3)在Redis绑定指定IP访问(位置配置文件[redis.config]中的bind节点)2.L ...

  7. Linux之强大的selinux

    简单点说,SELinux就是用来加强系统安全性的.它给一些特定程序(这些程序也在不断增加)做了一个沙箱,它将文件打上了一个安全标签,这些标签属于不同的类,也只能执行特定的操作,也就是规定了某个应用程序 ...

  8. TensorFlow 学习笔记(2)----placeholder的使用

    此系列将会每日持续更新,欢迎关注 在TensorFlow中输入值的方式是通过placeholder来实现 例如:做两个数的乘法时,是先准备好两个place, 再将输出值定义成两数的乘法 最后利用ses ...

  9. MongoDB - 增删改查及聚合操作

    目录 MongoDB - 增删改查及聚合操作 一. 数据库操作(database) 1. 创建及查看库 2. 删除库 二. 集合collectionc=操作(相当于SQL数据库中的表table) 1. ...

  10. Git 基础教程 之 别名

     配置别名, 例如:       git config --global alias.st status                                      git config ...