0

スレッドをテストするために並行処理クラスを作成しました。スレッドを同時に実行する最良の方法を見つけたかったからです。

私は自分の結果に驚いています:

test
test
Othertest
test
Othertest
test
test
test 

私が予想した結果は、スレッドがランダムに戻ってくるというものでしたが、一貫して同じ順序で戻ってきたようです! 誰かが理由を知っていますか?これは、それらが同時に実行されていないことを意味しますか? それらを同時に実行するにはどうすればよいですか?

これが私のコードです:

public class ThreadTest {
    public static void main(String args[]) throws InterruptedException
    {
        new Thread(new ThreadTest().test()).start();
        new Thread(new ThreadTest().test()).start();
        new Thread(new ThreadTest().otherTest()).start();
        new Thread(new ThreadTest().test()).start();
        new Thread(new ThreadTest().otherTest()).start();
        new Thread(new ThreadTest().test()).start();
        new Thread(new ThreadTest().test()).start();
        new Thread(new ThreadTest().test()).start();
    }

    public  Runnable test() throws InterruptedException{
        Thread.sleep((long) (Math.random()*1000));
        System.out.println("test");
        return null;
    }

    public  Runnable otherTest() throws InterruptedException{
        Thread.sleep((long) (Math.random()*1000));
        System.out.println("Othertest");
        return null;
    }

}
4

4 に答える 4

2

コンストラクターは、が最終的にメソッドを実行する をThread受け入れます。現在、オブジェクトを返していません。あなたは戻ってきています。したがって、andメソッドで行う実行は同期的に実行されます。RunnableThreadrun()Runnablenulltest()otherTest()

すべての実行は 1 つのスレッドで行われます。これ

new Thread(new ThreadTest().test()).start();

を実行test()し、1 秒間スリープし、出力"test"して を返しますnull。が であるため、呼び出しはstart()何もしません。これは、あなたが行う他の通話ごとに続きます。Runnablenull

メソッド内のメソッドtest()とメソッドにすべてを入れる必要があります。例えばotherTest()Runnable#run()

new Thread(new Runnable() {
    public void run() {
         Thread.sleep((long) (Math.random()*1000));
         System.out.println("test");
    }
}).start();

が呼び出されたときに実行されるクラスのrun()メソッドのソースコードを考えてみましょうThreadstart()

@Override
public void run() {
    if (target != null) {
        target.run();
    }
}

コンストラクターで渡す参照はどこtargetにありますか。Runnable明らかに、そうであればnull何もしません。

于 2013-09-02T04:29:24.090 に答える
1

これで運が良くなると思います:

public class ThreadTest {
public static void main(String args[]) throws InterruptedException
{
    new Thread(test).start();
    new Thread(test).start();
    new Thread(otherTest).start();
    new Thread(test).start();
    new Thread(otherTest).start();
    new Thread(test).start();
    new Thread(test).start();
    new Thread(test).start();
}

public static Runnable test = new Runnable() {
    @Override
    public void run()  {
        try {
            Thread.sleep((long) (Math.random()*1000));
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("test");
    }
};

public static Runnable otherTest = new Runnable() {
    @Override
    public void run(){
        try {
            Thread.sleep((long) (Math.random()*1000));
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Othertest");
    }
};

}

アイデアは、のインスタンスをRunnable引数としてThreadコンストラクターに渡すことです。test()otherTest()の両方が を返しているため、実際にはそうしていませんnull。上記のコードは、私が推測する方法でスレッドを実行する 1 つの方法を示しています。他のアプローチも確かに可能です。

于 2013-09-02T04:34:11.190 に答える
1

testメソッドとotherTestメソッドを実装として実装する必要がありますRunnable。そのようです:

private static class Test implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep((long) (Math.random()*1000));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return;
        }
        System.out.println("test");
    }
}

private static class OtherTest implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep((long) (Math.random()*1000));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return;
        }
        System.out.println("Othertest");
    }
}

public static void main(String args[]) {
    new Thread(new Test()).start();
    new Thread(new Test()).start();
    new Thread(new OtherTest()).start();
    new Thread(new Test()).start();
    new Thread(new OtherTest()).start();
    new Thread(new Test()).start();
    new Thread(new Test()).start();
    new Thread(new Test()).start();
}

もちろん、重複を少し減らすこともできます。

private enum Runnables implements Runnable {
    TEST {
        @Override
        public void run() {
            if (!sleep()) return;
            System.out.println("test");
        }
    },
    OTHER_TEST {
        @Override
        public void run() {
            if (!sleep()) return;
            System.out.println("Othertest");
        }
    };

    static boolean sleep() {
        try {
            Thread.sleep((long) (Math.random()*1000));
            return true;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }
}

public static void main(String args[]) {
    new Thread(Runnables.TEST).start();
    new Thread(Runnables.TEST).start();
    new Thread(Runnables.OTHER_TEST).start();
    new Thread(Runnables.TEST).start();
    new Thread(Runnables.OTHER_TEST).start();
    new Thread(Runnables.TEST).start();
    new Thread(Runnables.TEST).start();
    new Thread(Runnables.TEST).start();
}
于 2013-09-02T04:35:58.603 に答える
1

あなたのThread実装は間違っています。

メソッドを実装Runnableして実装run()するか、クラスを拡張してメソッドThreadをオーバーライドする必要がありますrun()

何が起こっているかというと、test()メソッドまたはメソッドotherTest()が呼び出されるのと同じように呼び出されます。run()また、メソッドがないため、Thread.start()単に何も実行しません。

以下のようにメソッドを変更してみてください。

public Runnable test() {
    return new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep((long) (Math.random() * 1000));
                System.out.println("test");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
}


public Runnable otherTest() {
    System.out.println("Othertest");
    return new Runnable() {

        @Override
        public void run() {
            try {
                Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("Othertest");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
}
于 2013-09-02T04:28:08.463 に答える