2013-01-06 14 views
18

mam tej klasy do tworzenia wątku w JavieJak poprawnie uzyskać nazwę wątku w Javie?

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(); 
      } 
     } 
    } 
} 

Konsola wyświetla następujący tekst jako wyjście

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

Mój kod, który tworzy nowy wątek:

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(); 
} 

Moje pytanie brzmi: dlaczego Thread.currentThread().getName() zwraca prawidłową nazwę nici, podczas gdy this.getName() zwraca inną?

Odpowiedz

39

Dlaczego Thread.currentThread().getName() zwraca prawidłową nazwę nici, podczas gdy this.getName() zwraca inną?

Twoja klasa DrawThreadextends Thread ale następnie go uruchomić poprzez wywołanie:

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

To nie jest poprawne. Oznacza to, że tworzony wątek jest , a nie tym samym z DrawThread. DrawThread powinien implementować Runnable i nie przedłużanie wątku. Twój kod działa, ponieważ wątek jest również runnable.

public class DrawThread implements Runnable { 

Ponieważ istnieją dwa obiekty wątek, kiedy zadzwonić this.getName() na obiekcie DrawThread że nie jest wątek, który jest faktycznie działa tak jej nazwa nie jest prawidłowo ustawiony. Określana jest tylko nazwa wątku zwijającego. Wewnątrz kodu DrawThread należy wywołać Thread.currentThread().getName(), aby uzyskać prawdziwą nazwę uruchomionego wątku.

Wreszcie, twoja klasa powinna prawdopodobnie być DrawRunnable, jeśli to implements Runnable. :-)

8

Przekazujesz instancję swojego DrawThread do konstruktora Thread(Runnable). Nie obchodzi cię, że twoja klasa rozszerza się o Thread; to tylko obchodzi, że to implements Runnable.

Wątek, który zaczyna się, jest utworzony przez new Thread(...) — i nie ustawiono na nim nazwy.

Ogólnie rzecz biorąc rozszerzenie Thread jest złym rozwiązaniem i należy go zawsze unikać. Już prawie jesteś, ponieważ nie instancja klasy, ale przekazujesz ją do osobnej instancji Thread.

3

Są to dwa obiekty: obiekt DrawThread zawierający metodę run i nowy wątek utworzony z użyciem Runnable.

this.getName uzyskuje nazwę nierozrestartowanego DrawThread. Bieżący wątek jest tym, który zacząłeś.

2

proste połączenie:

new DrawThread().start(); 

rozpocząć nowy wątek

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

(DrawThread rozciąga klasy gwintu) tak, polega na:

public synchronized void start() { 
     checkNotStarted(); 

     hasBeenStarted = true; 

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

U połączeń jest IKE PP NICI WEWNĄTRZ NICI (AS RUNNABLE), dzwoniąc pod numer:

public Thread(Runnable runnable) { 
    create(null, runnable, null, 0); 
}