0

1..n の数字で埋められた n のサイズの配列があります。

m 個のスレッドを使用してこの配列を合計する必要があります。毎回 2 つの要素を取り、それらを合計して、その合計を配列に挿入します。

これが私がやろうとしたことです。

最初に同期部分

public class MultiThreadedSum {

private ArrayBuffer ArrayBufferInst;
private int Sum;
private boolean Flag;

public MultiThreadedSum(ArrayBuffer ArrayBufferInst)
{
    this.ArrayBufferInst = ArrayBufferInst;
    Sum = 0;
    Flag = false;
}

public synchronized void Sum2Elements()
{

    while(Flag)
    {
        try {wait();}
        catch (InterruptedException e){}
    }

    Flag = true;

    if (ArrayBufferInst.RetunrSize() < 2)
    {
        return;
    }

    System.out.println("Removing 2 elements.");

    Sum = ArrayBufferInst.Sum2Elements();

    notifyAll();
}

public synchronized void InsertElement()
{

    while(!Flag)
    {
        try {wait();}
        catch (InterruptedException e){}
    }

    Flag = false;

    System.out.println("Inserting the sum.");

    ArrayBufferInst.InsertElement(Sum);

    notifyAll();
}

public int RetunrSize()
{
    return ArrayBufferInst.RetunrSize();
}

}

m 個のスレッドを 2 つのグループに分割しました。半分は要約を行い、半分は待機と通知を使用して追加を行います。

public class Sum2ElementsThread implements Runnable{

    private MultiThreadedSum MultiThreadedSumInst;    

    public Sum2ElementsThread( MultiThreadedSum MultiThreadedSumInst)
    {
        this.MultiThreadedSumInst = MultiThreadedSumInst;
    }

    @Override
    public void run() {

        while(MultiThreadedSumInst.RetunrSize() > 1)
        {
            MultiThreadedSumInst.Sum2Elements();
        }

    }

}

public class InsertThread implements Runnable{

    private MultiThreadedSum MultiThreadedSumInst;    

    public InsertThread( MultiThreadedSum MultiThreadedSumInst)
    {
        this.MultiThreadedSumInst = MultiThreadedSumInst;
    }

    @Override
    public void run() {

        while(MultiThreadedSumInst.RetunrSize() > 1)
        {
            MultiThreadedSumInst.InsertElement();
        }

    }

}

ここにメインの一部があります:

ArrayBufferInst = new ArrayBuffer(n);

MultiThreadedSumInst = new MultiThreadedSum(ArrayBufferInst);

ExecutorService Threads = Executors.newCachedThreadPool();

for (i = 0; i < m/2; i++)
{
    Threads.execute( new Sum2ElementsThread(MultiThreadedSumInst) );
}

for (; i < m; i++)
{
    Threads.execute( new InsertThread(MultiThreadedSumInst) );
}

while (MultiThreadedSumInst.RetunrSize() > 1){}

Threads.shutdown();

そしてバッファ

public class ArrayBuffer {

    private ArrayList<Integer> ArrayBufferInst;

    public ArrayBuffer(int SizeOfBuffer)
    {
        int i;

        ArrayBufferInst = new ArrayList<>(SizeOfBuffer);

        for (i = 0; i < SizeOfBuffer; i++)
        {
            ArrayBufferInst.add(i, i+1);
        }
    }

    public int Sum2Elements()
    {
        if (ArrayBufferInst.size() < 2)
        {
            return -1;
        }

        return ArrayBufferInst.remove(0) + ArrayBufferInst.remove(1);
    }

    public void InsertElement(int Elem)
    {
        ArrayBufferInst.add(Elem);
    }

    public int RetunrSize()
    {
        return ArrayBufferInst.size();
    }
}

多くの java.lang.IndexOutOfBoundsException および RangeCheck エラーが発生しています。これは、Sum2Elements の実装方法に関係している可能性がありますが、よくわかりません。

助けてくれる人はいますか?

ありがとう。

4

1 に答える 1

2

これが ArrayList で呼び出されたとき{a, b, c}

    if (ArrayBufferInst.size() < 2)
    {
        return -1;
    }

    return ArrayBufferInst.remove(0) + ArrayBufferInst.remove(1);

その後、ArrayBufferInst.remove(0)を取り外して戻りa、 に変更ArrayBufferInst{b, c}ます。呼び出すとcArrayBufferInst.remove(1)が削除されますが、これは必要なものではありません。したがって、1 を 0 に変更するだけです。

于 2013-05-21T18:36:45.563 に答える