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

これは正しくありません。これは、作成される実際のスレッドがから同じではないことを意味します。 スレッドを拡張するのではなく、実装する必要があります。そのはず:ThreadDrawThreadDrawThreadRunnable

public class DrawThread implements Runnable {

Threadもであるため、コードは機能しRunnableます。スレッドオブジェクトが2つあるため、実際に実行されているスレッドではないオブジェクトを呼び出すthis.getName()と、その名前が適切に設定されません。DrawThreadラッピングスレッドの名前のみが設定されます。DrawThreadコード内でThread.currentThread().getName()、実行中のスレッドの本当の名前を取得するために呼び出す必要があります。

最後に、あなたのクラスはおそらくそうあるべきDrawRunnableですimplements Runnable。:-)

于 2013-01-06T22:21:57.407 に答える
8

DrawThreadのインスタンスをThread(Runnable)コンストラクターに渡します。クラスが拡張されてもかまいませんThread; それだけが気になりimplements Runnableます。

開始されるスレッドはによって作成されたスレッドであり、そのスレッドnew Thread(...)に名前を設定していません。

一般に、拡張Threadは悪い習慣であり、常に避ける必要があります。クラスのインスタンスを作成していないので、もうほとんどそこにいますがstart、別のインスタンスに渡しThreadます。

于 2013-01-06T22:22:06.923 に答える
3

関連するオブジェクトは2つあります。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呼び出しは、次の呼び出しによってike PUT THREAD INSIDE THREAD(AS RUNNABLE)です。

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