当前位置:编程学习 > JAVA >>

在构造方法中将this传递给另外一个线程的疑问

在构造方法中将this传递给另外一个线程。

需求:一个线程,要监听所有manager的状态,在特定时刻改变manager的或调用manager的方法

代码:

public class Manager {
//还有很多属性
protected Manager(){
//初始化属性
Schedule.instance.addManager(this);
}
public void changeStatus() {
//具体业务

}


//单例
public class Schedule {

private CopyOnWriteArrayList<Manager> managerList = new CopyOnWriteArrayList<Manager>();
private ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(1);

public static final Schedule instance = new Schedule();
private Schedule(){
stpe.scheduleWithFixedDelay(new Monitor_Runnable(), 1, 1, TimeUnit.SECONDS);
}

//将manager加入到单例的Scheudle中
public void addManager(Manager manager){
this.managerList.add(manager);
}

//监听manager
class Monitor_Runnable implements Runnable{
@Override
public void run() {
for (Manager manager : managerList) {
//manager.的一些状态操作
manager.changeStatus();
}
}
}
}

问题:
在Manager的构造方法里,直接将this传递给了Schedule, 但是此时Manager还没有构造完成,而Schedule可能已经开始使用了
manager,这样会有问题吗?


--------------------编程问答-------------------- 没有问题,你这里传给addManager方法的参数并没有做什么调用操作。
public void addManager(Manager manager){
        this.managerList.add(manager);
}

还有,相信楼主见过下面的代码,肯定没问题吧
Person p = new Person("zhangsan", 20);

public class Person {
    public String name;
    public int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

     --------------------编程问答-------------------- 一般意义上说构造没有完成是说对象中有成员变量没有初始化,你的例子中没有这种情况。 --------------------编程问答-------------------- manager没有构造就不会调用,Schedule.instance.addManager(this);
那managerList就不会有值,Schedule开始了但managerList没值,不会进入循环,所以不会出错 --------------------编程问答--------------------
引用 3 楼 ncist_jianeng 的回复:
manager没有构造就不会调用,Schedule.instance.addManager(this);
那managerList就不会有值,Schedule开始了但managerList没值,不会进入循环,所以不会出错


我觉得你说的不对,只要调用了Schedule.instance.addManager(this);虽然没有构造完成,但是list还是会有manager的,举个例子:

public class Manager {

private ArrayList<Integer> list = new ArrayList<Integer>();
//还有很多属性
protected Manager(){

Schedule.instance.addManager(this);

try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}

//初始化属性
list.add(1);
list.add(1);
list.add(1);

System.out.println("construct finish...");
}
public void changeStatus() {
for (Integer i : list) {
System.out.println(i);
}

}



//单例
public class Schedule {

private CopyOnWriteArrayList<Manager> managerList = new CopyOnWriteArrayList<Manager>();
private ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(1);

public static final Schedule instance = new Schedule();
private Schedule(){
stpe.scheduleWithFixedDelay(new Monitor_Runnable(), 0, 1, TimeUnit.SECONDS);
}

//将manager加入到单例的Scheudle中
public void addManager(Manager manager){
this.managerList.add(manager);
}

//监听manager
class Monitor_Runnable implements Runnable{
@Override
public void run() {
for (Manager manager : managerList) {
manager.changeStatus();
System.out.println("execute monitor...");
}
}
}
}


public class Main {
public static void main(String[] args) {
Schedule s = Schedule.instance;
Manager m = new Manager();
}
}


输出:

execute monitor...
execute monitor...
construct finish...
1
1
1
execute monitor...


可以看到在Manager构造方法中,调研Schedule.instance.addManager(this);之后,休眠了3秒
但是在输出中还是会看到输出:
execute monitor...

等构造玩之后,才把真正把manager的list的值打印出来 --------------------编程问答--------------------
引用 2 楼 Lsheep 的回复:
一般意义上说构造没有完成是说对象中有成员变量没有初始化,你的例子中没有这种情况。


恩,构造没有完成是说对象中有成员变量没有初始化。上面的例子就好的反应了你说的,很正确!
谢谢
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,