1

私は現在、クリティカルセクションとセマフォについて学んでおり、この部分で行き詰まっています。皆さんが私に洞察を与えてくれることを願っています。

私はこれらの3つのタイプのスレッドを持っています:1つはスタックでpop()を実行し、もう1つは同じスタックでpush()を実行し、最後のスレッドはそのスタックの値を出力します。現時点では、クリティカルセクションとして想定したものにwait()とsignal()を配置しました。

class Example{

  public static void main(){

    //create thread objects
    StackPop p1 = new StackPop();
    StackPop p2 = new StackPop();
    StackPop p3 = new StackPop();

    StackPush ps1 = new StackPush();
    StackPush ps2 = new StackPush();
    StackPush ps3 = new StackPush();

    StackValues s1 = new StackValues();
    StackValues s2 = new StackValues();
    StackValues s3 = new StackValues();

    //then we start these threads in mix orders

    p1.start();
    s3.start();
    ps2.start();
    // etc
  }
}

class StackPop extends Thread{

  public void run(){

    mutex.wait();
    pop();
    SOP("value popped is " + get.popVal); 
    mutex.signal();

  }
}

class StackPush extends Thread{

  public void run(){

    mutex.wait();
    push();
    SOP("value inserted is " + get.pushVal);
    mutex.signal();

  }
}

class StackValues extends Thread{

  public void run(){

    mutex.wait();

    for(int i = 0; i<stack.size(); i++)
        S.O.P.("["+getVal(i)+"]");   //where getVal() will retrieve value at that index

    mutex.signal();
  }
}

上記のコードは簡略化されたバージョンですが、考え方は同じです。私の問題は、wait()とsignal()を使用したにもかかわらず、非常に奇妙な出力が得られることです。たとえば、出力の一部に「挿入された[1][2][3]の値は3[5][@] [@]」と表示されます(@は内部に数字がないことを意味します)。これは、forループが値を取得している間に、プロセッサが別のスレッドを実行させているためだと思います。wait()とsignal()によって自動的にアトミックになると思っていましたが、何かを見逃した可能性があります。

4

2 に答える 2

1

クリティカルセクションでロックまたは「同期」を使用できます。http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.htmlで詳細を確認 できます。 pop() push() などにも同じ考え方を使用できます。

ミューテックスあり。

try {
     mutex.acquire();
     try
     { 
     // work
     } finally {
     mutex.release();
  }
} catch(InterruptedException ie) {// ...}

ソース -> http://java.dzone.com/articles/dnp-java-concurrency- –-part-4

「私はこれらの 3 種類のスレッドを持っています。1 つはスタックで pop() を実行し、もう 1 つは同じスタックで push() を実行し、最後のスレッドはそのスタックの値を出力します」

スレッドごとに 3 つの異なるスタックを使用しているため、予期しないエラーが発生します。あるスタックで pop を作成し、別のスタックからプッシュし、最後に別のスタックから印刷します。

次のようなことをする必要があります:

public class Teste {

    Thread t1;
    Thread t2;
    Thread t3;

    Stack<Integer> stack = new Stack <Integer>();
    private final Semaphore mutex = new Semaphore(1);

    public Teste ()
    {
        Runnable r1 = new Runnable()                                                    
        {                                   
            public void run()
            {
            pop();
            } // run()
        }; // runnable


        Runnable r2 = new Runnable()                                                    
        {                   
            public void run()
            {
                for(int x = 0; x < 3; x++)
                   push(x);
            } // run()
        }; // runnable

        Runnable r3 = new Runnable()                                                    
        {                   
            public void run()
            {
                for(int x = 0; x < 3; x++)
                   print();
            } // run()
        }; // runnable

        this.t1 = new Thread(r1); // Create the thread associating the runnable
        this.t2 = new Thread(r2);
        this.t3 = new Thread(r3);
    }

    public void pop()
    {
        try {
            mutex.acquire();
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
        stack.pop();
        mutex.release();
    }

    // Similar to pop
    public void push(int x){ //..}

    public void print(){
        try {
            mutex.acquire();
        } catch (InterruptedException e) {e.printStackTrace();}

        for(int i = 0; i<stack.size(); i++)
            System.out.println("["+stack.get(i)+"]");

        mutex.release();
    }

}

public static void main(String argv[])
  {

    Teste t = new Teste();
    t.t2.start();
    t.t1.start();
    t.t3.start();
  }
于 2012-11-05T02:08:18.367 に答える
0

注意してください。wait は Object から継承されます。その反対は notify です。間違ったメソッドを呼び出している可能性があります。

また、Java にはネイティブの同期メカニズム、synchronized キーワードがあります。それを調査することをお勧めします。

于 2012-11-05T02:08:35.107 に答える