关闭

多线程/并发笔记:Java并发编程之this逃逸问题

标签: 多线程并发
147人阅读 评论(0) 收藏 举报
分类:

this逃逸是指在构造函数返回之前其他线程就持有该对象的引用. 调用尚未构造完全的对象的方法可能引发令人疑惑的错误。

this逃逸经常发生在构造函数中启动线程或注册监听器时, 如:

package com.mungo.lily.demo;

import com.mungo.lily.domain.MessageInfo;

public class ThisEscape {
    private String name;
    private Thread t;

    public static void main(String args[]) {
        try {
            ThisEscape te = new ThisEscape("ThisEscape ");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public ThisEscape() throws InterruptedException {
        t = new Thread(new EscapeRunnable());
        t.start();
        //其他操作。。。。
        Thread.sleep(2000);
        this.name = name;
    }

    private class EscapeRunnable implements Runnable {
        @Override
        public void run() {
            // 通过ThisEscape.this就可以引用外围类对象, 但是此时外围类对象可能还没有构造完成, 即发生了外围类的this引用的逃逸
            System.out.println(ThisEscape.this.info.toString());
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

上面的代码在编译的时候是没有问题的,可是在运行时报错。
这里写图片描述
这是因为,通过ThisEscape.this就调用了name的对象, 但是此时name对象可能还没有初始化完成, 所以输出的值就是null,即发生了外围类的this引用的逃逸。

所以,this逃逸问题的是需要避免的。因为这种问题在debug时是不容易发现的。上面的相同的代码,如果在System.out.println(ThisEscape.this.info.toString());这行代码的地方加个断点,等待一会,输出的时候是有值。
这里写图片描述
那么如何避免这个问题呢?当然,在构造函数中创建Thread对象是没有问题的, 但是不要启动Thread,所以可以提供一个init方法, 去启动进程,以保证在进程启动的时候所有的外围类对象都已完成初始化。即:

package com.mungo.lily.demo;

import com.mungo.lily.domain.MessageInfo;

public class ThisEscape {
    private String name;
    private Thread t;

    public static void main(String args[]) {
        try {
            ThisEscape te = new ThisEscape("ThisEscape");
            //启动进程
            te.init();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public ThisEscape(String name) throws InterruptedException {
        t = new Thread(new EscapeRunnable());
        //构造方法不启动进程
        //t.start();

        Thread.sleep(2000);
        this.name = name;
    }

    //启动进程
    public void init(){
        t.start();
    }

    private class EscapeRunnable implements Runnable {
        @Override
        public void run() {
            // 通过ThisEscape.this就可以引用外围类对象, 但是此时外围类对象可能还没有构造完成, 即发生了外围类的this引用的逃逸
            System.out.println(ThisEscape.this.name);
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

以上是参考Java并发编程之this逃逸问题,如有理解不当地方请指正。

1
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

java并发编程实践学习(四)对象的发布和逸出之this逃逸

《java并发编程实践》的第三章,对象的发布和逸出,作者提到了2种常见的对象逸出情况:在构造函数中注册事件监听,在构造函数中启动新线程。示例代码如下: public class ThisEscape ...
  • aitangyong
  • aitangyong
  • 2014-05-06 22:20
  • 3633

深入JAVA002_对象的发布和逃逸 --this解惑

最近研读java并发编程,其中作者在提到对象的发布和逃逸的时候,讲到两种可能会发生this发布和逃逸的用法,但是单凭文章不能很好理解,所以,查阅相关资料做了相关实验,做一下记录,以作备忘。 首先说明一...
  • u010001838
  • u010001838
  • 2015-05-13 13:15
  • 2302

JAVA多线程和并发基础面试题

多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。(校对注:非常赞同这个观...
  • dreamthen
  • dreamthen
  • 2014-05-23 11:28
  • 37836

java并发编程实践学习(四)对象的发布和逸出之this逃逸

《java并发编程实践》的第三章,对象的发布和逸出,作者提到了2种常见的对象逸出情况:在构造函数中注册事件监听,在构造函数中启动新线程。示例代码如下: public class ThisEscape ...
  • aitangyong
  • aitangyong
  • 2014-05-06 22:20
  • 3633

张孝祥Java多线程与并发库高级应用笔记

  • 2013-01-25 14:00
  • 695KB
  • 下载

学习Java多线程与并发编程后的笔记

Java多线程与并发编程笔记             在步入正题之前,简单的说几句,以示对这么伟大的事情留下一个见证。默默的在csdn上看博客啊,下载资料啊,学习新技术啊大概有三年的时间了,以前知识...
  • yjn198813
  • yjn198813
  • 2017-11-23 15:04
  • 43

java多线程中this与Thread.currentThread()返回值的引用问题

先看以下代码: public class Hello extends Thread {   public Hello(){ System.out.println("Thread.currentT...
  • kingbaron
  • kingbaron
  • 2016-03-17 21:32
  • 2101

java多线程中this与Thread.currentThread()返回值的引用问题

java多线程中this与Thread.currentThread()返回值的引用问题
  • kingbaron
  • kingbaron
  • 2017-02-19 21:08
  • 311

java多线程中this与Thread.currentThread()返回值的引用问题

http://blog.csdn.net/kingbaron/article/details/50917338 先看以下代码: public class Hello extends Threa...
  • u014507083
  • u014507083
  • 2016-11-15 21:53
  • 333

深入Java多线程和并发编程

  • 2014-08-25 17:03
  • 3.83MB
  • 下载