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