CurrentThread用法



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( null null "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()就会受到影响了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值