2013-01-06 43 views
18

我有这个类使用Java创建一个线程如何在Java中正确获取线程名称?

package org.vdzundza.forms; 

import java.awt.Graphics; 
import java.awt.Graphics2D; 

public class DrawThread extends Thread { 
    private static final int THREAD_SLEEP = 500; 
    public CustomShape shape; 
    private Graphics g; 

    public DrawThread(CustomShape shape, Graphics g) { 
     this.shape = shape; 
     this.g = g; 
    } 

    @Override 
    public void run() { 
     while (true) { 
      try { 
       Thread.sleep(THREAD_SLEEP); 
       Graphics2D g2d = (Graphics2D) g; 
       g2d.setColor(this.shape.getColor()); 
       g2d.fill(this.shape.getShape()); 
       System.out.println(String.format("execute thread: %s %s", 
         Thread.currentThread().getName(), this.getName())); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

控制台显示以下文本作为输出

execute thread: red rectangle Thread-2 
execute thread: yellow ellipse Thread-3 

我的代码,创建新的线程:

customShapes[0] = new CustomShape(
new Rectangle2D.Float(10, 10, 50, 50), Color.RED, 
    "red rectangle"); 
customShapes[1] = new CustomShape(new Ellipse2D.Float(70, 70, 50, 50), 
Color.YELLOW, "yellow ellipse"); 
for (CustomShape cshape: customShapes) { 
    Thread t = new Thread(new DrawThread(cshape, this.getGraphics()), 
    cshape.getName()); 
    threads.add(t); 
    t.start(); 
} 

我的问题是:为什么Thread.currentThread().getName()返回正确的线程名称,而this.getName()返回另一个?

回答

39

为什么Thread.currentThread().getName()返回正确的线程名称,而this.getName()返回其他?

DrawThreadextends Thread但你通过调用其启动:

new Thread(new DrawThread(...)); 

这是不正确的。这意味着创建的实际线程是而不是DrawThread相同ThreadDrawThread应该执行Runnable而不是扩展线程。你的代码可以工作,因为Thread也是一个Runnable。

public class DrawThread implements Runnable { 

因为有两个线程对象,当你DrawThread对象不是实际运行,所以它的名称设置不正确的线程上调用this.getName()。仅设置包装线程的名称。在DrawThread代码的内部,应该调用Thread.currentThread().getName()以获取运行线程的真实名称。

最后,你的班级应该是DrawRunnable,如果它implements Runnable。 :-)

8

您正在将DrawThread的实例传递给Thread(Runnable)构造函数。它不关心你的课程延伸Thread;它只关心它implements Runnable

开始的线程是由new Thread(...) —创建的线程,并且您没有在该线程上设置名称。

一般来说,延长Thread是不好的做法,应该始终避免。您已经差不多在那里了,因为您不需要start您班级的实例,而是将其传递给单独的Thread实例。

3

涉及到两个对象,包含Run方法的DrawThread对象以及使用它作为Runnable创建的新线程。

this.getName获取未启动的DrawThread的名称。当前线程是您开始的线程。

2

简单的调用:

new DrawThread().start(); 

开始新的线程

DrawThread drawThread;    // declare object of class DrawThread 
drawThread = new DrawThread();  // instantiate object of class DrawThread 
drawThread.start();     // call start to start DrawThread 

(DrawThread被扩展Thread类),因此涉及:

public synchronized void start() { 
     checkNotStarted(); 

     hasBeenStarted = true; 

     nativeCreate(this, stackSize, daemon); // here Thread is created 
    } 

ü打电话是IKE PUT螺纹内螺纹(AS RUNNABLE)致电:

public Thread(Runnable runnable) { 
    create(null, runnable, null, 0); 
} 
相关问题