最近在翻多线程的书,在看到一个this.currentThread().getName()和this.getName问题之后发现大家绕来绕去都一样。为何不用代码直接来解释,这是最简单的方式。
首先是Mythread类:
public class MyThread extends Thread{
public void run(){
synchronized (this) {
System.out.println("this.getname:"+this.getName());
System.out.println("this.currentThread():"+this.currentThread().getName()+" begin");
System.out.println("this.currentThread():"+this.currentThread().getName()+" end");
}
}
}
ShrareThread,请无视我这不规范的命名。
public class ShareThread {
public static void main(String[] args) {
MyThread m = new MyThread();
Thread t = new Thread(m, "a");
Thread t2 = new Thread(m, "b");
Thread t3 = new Thread(m, "c");
t.start();
t2.start();
t3.start();
MyThread m2 = new MyThread();
Thread t4 = new Thread(m2, "a");
t4.start();
}
}
输出 :
this.getname:Thread-0
this.currentThread():a begin
this.currentThread():a end
this.getname:Thread-0
this.currentThread():b begin
this.currentThread():b end
this.getname:Thread-0
this.currentThread():c begin
this.currentThread():c end
this.getname:Thread-1
this.currentThread():a begin
this.currentThread():a end
这里有个特别的构造方法。Thread(Runnable target,String name)
target是该线程启动的时候,该对象的run方法被调用,name是新线程的名字。
这样设计的目的,个人猜测,在于java没用多继承,想让其他线程调用一个线程的方法,或者共享变量时,可以通过这种方式。本身Thread实现Runnable接口。
currentThread是代码被调用的线程。this指的是当前对象的引用,所以调用MyThread引用的线程就是t,Thread t = new Thread(m, "a");通过这样构造之后,将t的name更改为a。所以this.currentThread().getName()获取为a,b,c。
this指的是当前对象的引用,因为引用为MyThread实例,MyThread又继承Thread,所以getName其实调用的就是Thread的getName方法。
由于默认构造方法中,name属性默认值为Thread-加上数字。所以this.getName取得的就是MyThread这个线程实例的name。所以获取到的是Thread-加数字。
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null);
}
照猫画虎,我们可以改下代码,便能清楚的看到name的改变。
public class MyThread extends Thread{
public MyThread(){
this.setName("a");
}
public void run(){
synchronized (this) {
System.out.println("this.getname:"+this.getName());
System.out.println("this.currentThread():"+this.currentThread().getName()+" begin");
System.out.println("this.currentThread():"+this.currentThread().getName()+" end");
}
}
public static void main(String[] args) {
MyThread m = new MyThread();
m.start();
}
}
输出:
this.getname:Thread-0
this.currentThread():Thread-0 begin
this.currentThread():Thread-0 end
this和this.currentThread()指的都是新建的MyThread这个线程对象。所以getName拿到的值是相同的。
public MyThread(){
this.setName("a");
}
在默认的构造方法就修改name属性,此时输出:
this.getname:a
this.currentThread():a begin
this.currentThread():a end
这样看来,当你不懂当前代码的含义的时候,自己要多动手去试,用不同的思路方法去尝试,结果就是你理解了的最好的证明。