2013-01-06 41 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); 
} 
相關問題