Подтвердить что ты не робот

Как правильно получить имя потока в 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() возвращает другое?

4b9b3361

Ответ 1

Почему Thread.currentThread().getName() возвращает правильное имя потока, а this.getName() возвращает другое?

Ваш DrawThread класс extends Thread, но затем запустите его, вызвав:

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

Это неверно. Это означает, что созданный фактический поток не является тем же Thread из DrawThread. DrawThread должен реализовывать Runnable и не расширять поток. Ваш код работает, потому что Thread также является Runnable.

public class DrawThread implements Runnable {

Потому что есть два объекта потока, когда вы вызываете this.getName() на объект DrawThread, который не является потоком, который фактически запущен, поэтому его имя неправильно установлено. Установлено только имя потока обертки. Внутри кода DrawThread вы должны вызвать Thread.currentThread().getName(), чтобы получить истинное имя текущего потока.

Наконец, ваш класс должен быть DrawRunnable, если он implements Runnable.: -)

Ответ 2

Вы передаете экземпляр своего DrawThread в конструктор Thread(Runnable). Не волнует, что ваш класс расширяет Thread; он заботится только об этом implements Runnable.

Запустившийся поток - это тот, который создан new Thread(...) — и вы не указали имя на этом.

В общем, расширение Thread является плохим практическим опытом и его всегда следует избегать. Вы уже почти там, потому что вы не start экземпляр своего класса, но передаете его отдельному экземпляру Thread.

Ответ 3

В объекте задействованы два объекта: объект DrawThread, содержащий метод запуска, и новый поток, созданный с использованием его как Runnable.

this.getName получает имя неартерированного DrawThread. Текущий поток - это тот, который вы начали.

Ответ 4

простой вызов:

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 вызов isike PUT THREAD INSIDE THREAD (AS RUNNABLE), вызывая:

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