您的位置:首页 > 其它

多线程--this和Thread.currentThread()详解

2018-03-27 21:09 513 查看
在看多线程编程核心技术的时候,有一段代码让我很困惑,所以在这里记录一下。
public class isalive {

public static void main(String[] args) {
// TODO Auto-generated method stub
//Thread.currentThread().getName();
CountOperate countOperate=new CountOperate();
Thread t1=new Thread(countOperate);
System.out.println("main begin t1 isalive  "+t1.isAlive());
t1.setName("a");
t1.start();
System.out.println("main end  "+t1.isAlive());
}

}

class CountOperate extends Thread{
public CountOperate(){
System.out.println("构造函数begin");
System.out.println("Thread.currentThread().getName()  "+Thread.currentThread().getName());
System.out.println("Thread.currentThread().isAlive()  "+Thread.currentThread().isAlive());

System.out.println("this.getname  "+this.getName());
System.out.println("this.Alive  "+this.isAlive());
System.out.println("测试:"+Thread.currentThread().getName()==this.getName());//添加的代码,为了测试是否相等
System.out.println("构造函数end  ");
}
public void run(){
System.out.println("run begin");
System.out.println("Thread.currentThread().getName()  "+Thread.currentThread().getName());
System.out.println("Thread.currentThread().isAlive()  "+Thread.currentThread().isAlive());
System.out.println("测试:"+Thread.currentThread().getName()==this.getName());//为了测试是否相等
System.out.println("this.getname  "+this.getName());
System.out.println("this.Alive  "+this.isAlive());
System.out.println("run end");
}
}
问题就是这边的Thread.currentThread()和this有上面不同,我们先看一下运行之后的输出。



首先从第2,3行输出可以知道,countoperate的构造函数是在主线程中运行的,这个没有疑问。
第3,4行输出了thread-0,和false,Thread.currentThread()和this也并不是一个引用,因为this指向的是countoperate对象实例,该实例继承thread,可以调用其中的getname(),isalive()方法。然后我就想知道为什么它这边this.getname()为什么会拿出个thread-0出来。我们来看源码。
首先是thread的构造函数 public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
private static int threadInitNumber;//线程的id也就是通过这个静态变量来设置的。
nextThreadNum()方法 private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
在进去Init()方法,因为这个方法里面东西很多,我们只看我们需要的,name参数 private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
        this.target=target;
this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
this.name = name.toCharArray();//在这里将传入的参数赋值给name,也就是线程的名称,在通过getname()来获取。继续往下看,从run函数里面的输出可以知道,当countoperate作为参数传给t1线程,t1线程开启时,这时候this指向的还是new countoperate的线程实例,而不是线程t1,为什么呢?明明是用线程t1开启调用run方法啊。
还是要看thread源码中另一个构造函数,countoperate作为target参数传给这个线程,当执行t1.run()的时候,本质上调用还是target.run().所有this,getname()得到的还是thread-0. public void run() {
if (target != null) {
target.run();
}
}
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: