26

我有这个类用于在 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

4 回答 4

57

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

您的DrawThread课程extends Thread,但随后您通过以下方式开始:

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

这是不正确的。这意味着创建的实际线程 与Thread. 应该实现而不是扩展线程。它应该是:DrawThreadDrawThreadRunnable

public class DrawThread implements Runnable {

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

最后,你的课应该是DrawRunnableif it implements Runnable。:-)

于 2013-01-06T22:21:57.407 回答
8

您正在将您的实例传递DrawThreadThread(Runnable)构造函数。它不在乎您的课程是否扩展Thread;它只关心它implements Runnable

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

一般来说,扩展Thread是不好的做法,应始终避免。您已经快到了,因为您没有start类的实例,而是将其传递给单独的Thread实例。

于 2013-01-06T22:22:06.923 回答
3

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

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

于 2013-01-06T22:22:43.273 回答
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 is ike PUT THREAD INSIDE THREAD (AS RUNNABLE) 通过调用:

public Thread(Runnable runnable) {
    create(null, runnable, null, 0);
}
于 2015-06-29T18:47:37.953 回答