1

スレッドを拡張するクラスがあると仮定します。

だから私がこれまでに知っていることから:

  • このrun()メソッドは、直接呼び出されると通常のメソッドと同じように扱われ、JVM が新しいスレッドを作成することはありません。

  • 意図したとおりに動作させるには、メソッドを呼び出す必要があり、 OS のダークジュジュ マジックが発生した後start()、メソッドがメソッドを呼び出します。run()

私の質問は:

誰かがオーバーロードstart()/run()して通常の動作を維持できる方法はありますか?

注: あなたは好奇心と愚かさを取り違えています。無礼になる必要はありません。

4

6 に答える 6

5

のまたはメソッドをそれぞれThread呼び出すことにより、をサブクラス化すると、これを行うことができます。ただし、基になるコードにパラメーターを渡す場合は、代わりに を実装し、パラメーターをその状態に保つことをお勧めします。ThreadstartrunRunnable

class MyRunnable implements Runnable {

    private final int a;
    private final int b;

    public MyRunnable(int a, int b) {
        this.a = a;
        this.b = b;
    }

    @Override
    public void run() {
        // do something with a and b
    }   
}

abは、このサンプルでは「パラメーター」のようなものです。コンストラクターでインスタンスを aに渡すことThreadできます。start

于 2012-09-27T08:30:20.940 に答える
3

Threadクラスのstartメソッドとrunメソッドはfinalメソッドではないため、Threadのstart/runメソッドをオーバーライドできます。例:isAlive()、stop()、suspend()、join()は最終メソッドです。したがって、Uはオーバーライドできません。

public class TempThread extends Thread
{
    @Override
    public synchronized void start() {
        // TODO Auto-generated method stub
        super.start();
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
    }       

    public static void main(String[] args) 
    {
        TempThread t = new TempThread();
        t.start();
        t.run();
    }
}

しかし、あなたがオーバーロードについて尋ねたように

これらのメソッドのいずれかをオーバーロードできます。

元 :

public class TempThread extends Thread
{
    @Override
    public synchronized void start() {
        // TODO Auto-generated method stub
        super.start();
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
    }

    // ******** Overload **********
    public synchronized void start(int i) {
        // TODO Auto-generated method stub
        super.start();
    }

    // ********* Overload **********
    public void run(int i) {
        // TODO Auto-generated method stub
        super.run();
    }

    public static void main(String[] args) 
    {
        TempThread t = new TempThread();
        t.start();
        t.run();
    }   
}

注:オーバーライドとオーバーロードの違いを確認してください。これにより、問題についての理解が深まります。

于 2012-09-27T09:33:27.670 に答える
3

もちろん:

class StupidThread extends Thread {
    @Override
    public void start() {
        run();
    }
}

しかし、なぜこれを行うのですか?JVM で作成されたすべてのスレッドに対してグローバルにこれを行うことはできませんが、StupidThreadどこでも自由に使用できます。

于 2012-09-27T08:25:27.193 に答える
2

1つの代替方法は、の匿名インスタンスを作成することですRunnable。これにより、(を作成するメソッドの)最終ローカル変数と最終パラメーター、Runnableおよびを作成するクラスのフィールドにアクセスできるようになりますRunnable。さらに、囲んでいるクラスのメソッドにもアクセスできます。

例えば。

class SomeClass {

    // constructor, getter and setter not included for brevity

    private String field;

    public void startNewThread(final String parameter) {
        final double local = Math.random();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(field + parameter + local);
            }
        }).start();
    }
}

警告:囲んでいるクラスは別のスレッドによって変更される可能性があるため、古い値を取得するときに、非最終フィールドに直接アクセスすることはお勧めしません。同期されたゲッターでアクセスするか、finalフィールド(オブジェクトの場合は内容が不変)にのみアクセスします。

于 2012-09-27T09:05:44.200 に答える
2

メソッドのオーバーロードを使用する場合は、run()メソッドの本体からこれを行う必要がありますrun()。もちろん、そうしている場合は、メソッドを呼び出さないこともできますrun()

start()メソッドのオーバーロードについて。pthread_create()または類似のメソッドを呼び出してからメソッドを呼び出す JNI メソッドと考えることができますrun()。実際には、パフォーマンス上の理由から、おそらく異なる方法で実装されています。あなたはそれに干渉しないのが一番です。ただし、このページの最初の例に示すように、スレッド コンストラクターをオーバーロードすることを検討できます: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html

 class PrimeThread extends Thread {
     long minPrime;
     PrimeThread(long minPrime) {
         this.minPrime = minPrime;
     }

     public void run() {
         // compute primes larger than minPrime
          . . .
     }
 }
于 2012-09-27T08:32:49.377 に答える
0

super.start() の呼び出しに基づく上記の方法は、期待どおりに並列化されないことがわかりました。これに対する 1 つの回避策は、引数をメンバー変数としてスレッドのサブクラスに渡すことです。

public class MyRunnable extends Thread {
    private int id=0;
    MyRunnable(int i){
    this.id=i;
}


public void run() {
    System.out.println("Starting run: " + (id+1));
    try {
        TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("Finishing run: " + (id+1));
}

public static void main(String args[]) {
    MyRunnable threadArray[] = new MyRunnable[5];
    for (int j = 0; j < 5; j++) {
        threadArray[j] = new MyRunnable(j);
        threadArray[j].start();
    }
}


}

ここでは明らかにコンストラクターを使用しましたが、run() メソッドを呼び出す前にセッター メソッドを使用することもできます。

于 2017-01-04T11:02:20.757 に答える