2

優先度の高いスレッドと優先度の低いスレッドの 2 つのスレッドをテストしようとしています。

私の結果によると、優先度の低いスレッドの方が速い場合がありますが、これはどのように可能ですか? 各スレッド内でクリック変数をインクリメントすることにより、さまざまな優先度のスレッドをテストしました。睡眠時間も増減しましたが、何もありません。

バックグラウンドで重いプログラムを実行せずにテストしていたので、HD ムービーを実行してテストすることにしましたが、それでも実際の変化はなく、スレッドは常に同じ速度です。

私のPCはIntel i5です。Windows 7 64ビット、16GB RAMを実行しています

これはコードです:

class clicker implements Runnable{
    long click =0;
    Thread t;
    private volatile boolean running = true;

    clicker(int p){
        t=new Thread(this);
        t.setPriority(p);
    }

    public void run(){
        while(running)
            click++;
    }

    public void stop(){
        running = false;
    }

    public void start(){
        t.start();
    }
}




class HiLoPri {
public static void main(String args[]){
    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    clicker hi=new clicker(Thread.NORM_PRIORITY+4);
    clicker lo=new clicker(Thread.NORM_PRIORITY-4);

    lo.start();
    hi.start();
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {

        e.printStackTrace();
    }
    lo.stop();
    hi.stop();

    try {
        hi.t.join();
        lo.t.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("LO: "+lo.click);
    System.out.println("HI: "+hi.click);
 }  
}
4

2 に答える 2

3

2 つの問題があります。1 つは、スレッドの開始に時間がかかることです。そのため、スレッドを連続して起動することで、"Low" にかなり有利なスタートを切ることができます。もう 1 つは、プロセッサ時間の引数がある場合に、スレッドの優先度によって誰が実行されるかが決まることです。2 つのスレッドと 8 つの有効なプロセッサ コアがあるため、優先度はそれほど重要ではありません。これは、ラッチを使用してすべてのスレッドを「同時に」開始し、実際にリソースを争うのに十分な数のスレッドを使用する修正された例です。優先度設定の効果を確認できます。かなり一貫した結果が得られます。

static class Clicker implements Runnable{
    BigInteger click = BigInteger.ZERO;
    Thread t;

    Clicker(int p){
        t=new Thread(this);
        t.setPriority(p);
    }

    public void run(){
        try {
        latch.await();
        } catch(InterruptedException ie) {}
        while(running)
            click = click.add(BigInteger.ONE);
    }

    public void start(){
        t.start();
    }
}

public static volatile boolean running = true;
public static final CountDownLatch latch = new CountDownLatch(1);

public static void main(String args[]){
    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    List<Clicker> listLow = new ArrayList<Clicker>();
    List<Clicker> listHigh = new ArrayList<Clicker>();
    for (int i = 0; i < 16; i++) {
        listHigh.add(new Clicker(Thread.NORM_PRIORITY+4));
    }
    for (int i = 0; i < 16; i++) {
        listLow.add(new Clicker(Thread.NORM_PRIORITY-4));
    }
    for (Clicker clicker: listLow) {
        clicker.start();
    }
    for (Clicker clicker: listHigh) {
        clicker.start();
    }
    latch.countDown();
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {

        e.printStackTrace();
    }
    running = false;

    BigInteger lowTotal = BigInteger.ZERO;
    BigInteger highTotal = BigInteger.ZERO;
    try {
        for (Clicker clicker: listLow) {
            clicker.t.join();
            lowTotal = lowTotal.add(clicker.click);
        }
    for (Clicker clicker: listHigh) {
            clicker.t.join();
            highTotal = highTotal.add(clicker.click);
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("LO: "+lowTotal);
    System.out.println("HI: "+highTotal);
 }  
于 2013-04-29T23:23:10.080 に答える
2

スレッドの優先順位は、効果があるとは限りません。これは、JDK javadocs を含む複数の場所で言及されています。したがって、実行しているプラ​​ットフォームで基本的にレベルを無視すると仮定すると、基本的な統計確率に戻ります。スケジューラの動作方法などによっては、一部のスレッドが他のスレッドよりも速く実行されるように見えることがあります。

Java スレッドの優先順位がすべての処理 (または優先順位の欠如) がせいぜいプラットフォームに依存していることを考えると、Java スレッドの優先順位を実際に使用している人はいないと思います。

于 2013-04-29T23:10:04.093 に答える