CurrentThread用法

原创 2016年06月02日 09:45:11


public class CurrentThreadTest {


public static void main(String[] args) {
// System.out.println(Thread.currentThread().getName());
Thread td = new TestThread();
td.run();
}
}
class TestThread extends Thread{
public TestThread(){
System.out.println("构造函数:" + Thread.currentThread().getName());
}
@Override
public void run() {
System.out.println("run:" + Thread.currentThread().getName());
}

}

构造函数:main
run:main

构造函数,是主线程main调用

run方法,不是启动线程的方法,直接用对象调用,也是主线程调用

start方法,是启动线程的方法,由当前线程调用。run方法是自动调用的方法

=============================================================================================================

public class CountOperate extends Thread {
public CountOperate() {
System.out.println("CountOprrate -----> begin");
System.out.println("CurrentThread:" + Thread.currentThread().getName());
System.out.println("This Name:" + this.getName());
System.out.println("CountOprrate -----> end");
}


@Override
public void run() {
System.out.println("Run -----> begin");
System.out.println("CurrentThread:" + Thread.currentThread().getName());
System.out.println("This Name:" + this.getName());
System.out.println("Run -----> end");
}


public static void main(String args[]) {
CountOperate ce = new CountOperate();
ce.setName("A");
ce.start();  

}
}

运行结果如下

CountOprrate -----> begin
CurrentThread:main
This Name:Thread-0     //默认的线程名字
CountOprrate -----> end
Run -----> begin
CurrentThread:A     //重新设置线程名字
This Name:A
Run -----> end

==============================================================================================================

public class CountOperate extends Thread {
public CountOperate() {
System.out.println("CountOprrate -----> begin");
System.out.println("CurrentThread:" + Thread.currentThread().getName());
System.out.println("This Name:" + this.getName());
System.out.println("CountOprrate -----> end");
}


@Override
public void run() {
System.out.println("Run -----> begin");
System.out.println("CurrentThread:" + Thread.currentThread().getName());
System.out.println("This Name:" + this.getName());
System.out.println("Run -----> end");
}

public static void main(String args[]) {
CountOperate ce = new CountOperate();     //创建的线程对象 0
Thread td = new Thread(ce);   //又封装了一个线程对象1
td.setName("A"); 
td.start();

}

CountOprrate -----> begin
CurrentThread:main
This Name:Thread-0   //第一个构造函数调用的时候CountOperate ce = new CountOperate();     //创建的线程对象 0,this.getName是第一个线程0
CountOprrate -----> end
Run -----> begin
CurrentThread:A //调用start方法后,线程名字改为A,若不设置线程名字,默认是Thread-1
This Name:A
Run -----> end



CountOprrate -----> begin
CurrentThread:main
This Name:Thread-0
CountOprrate -----> end
Run -----> begin
CurrentThread:Thread-1
This Name:Thread-0
Run -----> end

============================================================

剖析:

首先要清楚thread和t1是两个完全不同的对象,他俩之间唯一的关系就是把thread传递给t1对象仅仅是为了让t1调用thread对象的run方法。hello thread = new hello();运行这句话的时候会调用hello的构造方法,Thread.currentThread().getName()是获得调用这个方法的线程的名字,在main线程中调用的当然是main了,而this.getName()这个方法是获取当前hello对象的名字,只是单纯的方法的调用。因为没有重写这个方法所以调用的是父类Thread(把这个对象当作是普通的对象)中的方法。

Java code
?
1
2
3
4
5
6
7
this.getName()-->public final String getName() {
    return String.valueOf(name);
    }-->所以最终是输出name的值,因为你在hello的构造方法中没有显式调用父类的所以调用的是默认无参的public Thread() {
    init(nullnull"Thread-" + nextThreadNum(), 0);
    }-->最终的名字就是这个"Thread-" + nextThreadNum()-->private static synchronized int nextThreadNum() {
    return threadInitNumber++;
    }-->private static int threadInitNumber;因为是第一次调用nextThreadNum() 方法所以返回值为0-->this.getName()=Thread-0
后面的输出类似。t1.setName("A");这句话只是修改了t1的名字,和thread对象没有关系,所以run方法中this.getName()的输出还是Thread-0。
===================================================================

Thread中的setName方法


private char        name[];

public final void setName(String name) {   //final类型,不能覆盖了

        checkAccess();
        this.name = name.toCharArray(); //name是数组形式
    }


   public final String getName() {  // getName也是final类型,不能覆盖

        return String.valueOf(name); //name是数组形式
    }

=============================================================================

 public Thread(Runnable target) { 
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

  /**
     * Initializes a Thread with the current AccessControlContext.
     * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext)
     */
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null);
    }



    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }


        this.name = name.toCharArray();



        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            /* Determine if it's an applet or not */


            /* If there is a security manager, ask the security manager
               what to do. */
            if (security != null) {
                g = security.getThreadGroup();
            }


            /* If the security doesn't have a strong opinion of the matter
               use the parent thread group. */
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }


        /* checkAccess regardless of whether or not threadgroup is
           explicitly passed in. */
        g.checkAccess();


        /*
         * Do we have the required permissions?
         */
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }


        g.addUnstarted();


        this.group = g;
        this.daemon = parent.isDaemon();
        this.priority = parent.getPriority();
        if (security == null || isCCLOverridden(parent.getClass()))
            this.contextClassLoader = parent.getContextClassLoader();
        else
            this.contextClassLoader = parent.contextClassLoader;
        this.inheritedAccessControlContext =
                acc != null ? acc : AccessController.getContext();
        this.target = target;
        setPriority(priority);
        if (parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;


        /* Set thread ID */
        tid = nextThreadID();
    }


public final String getName() {  // getName也是final类型,不能覆盖

        return String.valueOf(name); //name是数组形式
    }


CountOperate ce = new CountOperate();     //创建的线程对象 0
Thread td = new Thread(ce);   //又封装了一个线程对象1
td.setName("A"); 
td.start();


this.getName和Thread.currentThread().getName()不一样。currentThread().getName()获取当前调用该方法的线程的名称;

this.getName当前对象的名称

Thread子类的getName()方法当然是从Thread中继承过来的,由于Thread中的getName方法是final类型的,所以Thread子类不能对该方法进行覆盖。this.getName()中this表示本类,super表示父类,一般this可以忽略,只是某些时候如果子类覆盖了父类中方法,用this.getName(),super.getName()代码上更清晰。这里不能覆盖this.getName(),super.getName(),getName()都一样。
总结:

supr和this只有子类继承父类,并且父类掉用子类的时候才能使用,否则其他情况下supr,this一样,用不用无所谓

之所以super.getName()与super.getName()一样,是因为,第一次创建对象CountOperate ce = new CountOperate();   的时候,生成了一个线程名字,

这个线程对象和下面的Thread不是一回事,它继承的也不是td所在的Thread,所以td所在的Thread对 super.getName()没有任何影响。

ce对this.getName()或super.getName()才有直接且真正的影响,构造函数在前,set在后,所以构造函数中的this.getName()不受ce.setName()影响。

ce.start();之后,自动调用run()方法,run()方法中的this.getName()就会受到影响了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

ClassLoader,Thread.currentThread().setContextClassLoader,tomcat的ClassLoader

http://www.cnblogs.com/549294286/p/3714692.html ClassLoader,Thread.currentThread().setCon...

currentThread().getName和this.getName()的区别

currentThread().getName()方法:返回代码段正在被哪个线程调用的name信息。 this.getName()方法:是获取当前对象的名字,只是单纯的方法调用 class Count...

JAVA多线程编程之Thread中This和Thread.CurrentThread的区别

JAVA多线程编程之Thread中This和Thread.CurrentThread的区别 this代表当前的线程类,,Thread.CurrentThread代表正在执行的线程,看例子就懂了: ...

Thread.currentThread().getContextClassLoader()与Test.class.getClassLoader()区别

原文章地址:http://blog.csdn.net/truong/article/details/34436367 忘记以前有没有问过这个问题,总之我现在有看到几个地方有这个: Thread.c...

从头认识多线程-1.3 currentThread()

这一章节我们来讨论一下currentThread()。我们下面通过一段代码来解释几个问题:package com.ray.deepintothread.ch01.topic_3; public cl...

读取配置文件Properties的一种方案(Thread.currentThread().getContextClassLoader() .getResourceAsStream()

Java路径   Java中使用的路径,分为两种:绝对路径和相对路径。

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

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

Class.forName() 初始化、Thread.currentThread().getContextClassLoader().getResourceAsStream

Class.forName() 和 ClassLoader.loadClass()的区别? Class.forName() 和 Class.forName().NewInstance()的区别? ...

线程的创建之继承Thread类、线程的生命周期、线程常用的方法、currentThread方法详解

一、线程的创建 1、如何在自定义的代码中,自定义一个线程呢? 通过对API文档的查找,java已经提供了对线程这类事物的描述——Thread类。2、创建线程的第一种方式:继承Thread类。 1...

Thread.currentThread().getContextClassLoader()与Test.class.getClassLoader()区别

 忘记以前有没有问过这个问题,总之我现在有看到几个地方有这个: Thread.currentThread().getContextClassLoader() 我总是想不出在什么情况下会用这种...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)