0

私はJavaのスレッドについて少し学んでいるところですが、誰かが私を助けてくれるかどうか疑問に思っていました。

10個の整数のリストを作成しました。私がやりたいのは、複数のスレッドを入れて、インデックス0の整数を取得し、それを印刷して削除することです。リストに数字がなくなるまでこれを実行したいと思います。これはこれまでの私のコードです。

public class SlothTest implements Runnable{

static ArrayList<Object> test = new ArrayList<>();
static int listSize;

public static void main(String[] args) {

    for (int i = 0; i < 10; i++){
        test.add(i);
    }

    SlothTest runner = new SlothTest();
    Thread alpha = new Thread(runner);
    Thread beta = new Thread(runner);
    alpha.setName("Alpha thread");
    beta.setName("Beta thread");
    alpha.start();
    beta.start();
}

@Override
public void run() {
    listSize = test.size();
    while (listSize > 0){
        getLink();
    }
}

private synchronized void getLink(){
    String threadName = Thread.currentThread().getName();
    System.out.println(threadName + " printed " + test.indexOf(listSize - 1));
    test.remove(0);
    listSize = test.size();
}

}

誰かが私が間違っていることすべてを指摘するのを手伝ってもらえますか、それはおそらくたくさんあります。

4

3 に答える 3

0

のテストがlistSize > 0正しく同期されていません。チェックの実行時にはリストが空でなくても、スレッドが を呼び出すまでには実際には空になっている可能性がありますgetLink()。リストが空であることを示し、そうではないことを示すvoid の代わりにgetLink()returnを使用する方がおそらく簡単でしょう。各スレッドは、返されるまでメソッドを呼び出し続けることができます。また、アイテムを削除しようとする前に、の上部にあるリストが空でないことを確認する必要があります。booleantruefalsefalsegetLink()

@Override
public void run() {
    while (getLink());
}

private synchronized boolean getLink(){
    String threadName = Thread.currentThread().getName();
    System.out.println(threadName + " printed " + test.indexOf(test.size() - 1));
    if(!test.isEmpty()){
        test.remove(0);
    }
    return !test.isEmpty()
}
于 2012-09-07T13:52:42.067 に答える
0

同期されたスピンロックはシングル スレッド アプリケーションと (ほぼ) 同じように動作するため、マルチスレッド メソッドでインデックス 0 の要素を取得しても意味がありません。複数のスレッドが読み取ることができますが、書き込むことができるのは 1 つだけです。

于 2012-09-07T13:53:41.730 に答える
0

基本的な問題は、1 つのスレッドで実行するのが最適な何かを実行しているということです。JVM はこれを処理しますが、1 つのスレッドがロックをロックし、他のスレッドがチャンスを得る前にすべての要素を消費できるようにします。

于 2012-09-07T13:53:43.320 に答える