如何在Java中正确获取线程名称?

28

我有一个用于在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()返回另一个名称?
4个回答

59

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

你的DrawThreadextends Thread,但是你通过以下方式启动它:

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

这不是正确的。它意味着实际创建的线程并不是来自DrawThread的同一个ThreadDrawThread 应该实现 Runnable,而不是继承线程。应该这样写:

public class DrawThread implements Runnable {

你的代码之所以能够工作,是因为Thread也是一个Runnable。由于存在两个线程对象,当你在DrawThread对象上调用this.getName()时,并不是实际运行的线程,因此它的名称没有正确设置。只有包装线程的名称被设置。在DrawThread代码内部,应该调用Thread.currentThread().getName()来获取正在运行的线程的真实名称。

最后,如果你的类implements Runnable,那么它应该可能被命名为DrawRunnable。 :-)


8
您正在将您的DrawThread实例传递给一个Thread(Runnable)构造函数。它并不关心你的类是否扩展了Thread,它只关心它实现了Runnable接口。

启动的线程是由new Thread(...)创建的 - 而您没有为该线程设置名称。

一般来说,扩展Thread是不好的做法,应该尽量避免。你已经快完成了,因为你不会start你的类的实例,而是将其传递给一个单独的Thread实例。


3

涉及到两个对象,一个是包含run方法的DrawThread对象,另一个是使用它作为可运行对象创建的新线程。

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 
  }

您可以通过调用 将线程放入线程(作为可运行项) 的方式来调用 u call:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接