1

2 つのスレッドを 1 つの Ping と 1 つの Pong にしようとしています。Ping は常に最初に実行する必要があるという考えです。同期メソッドを使用しています。ここで私のコードの何が問題なのかわかりません。それはうまくいくはずです。私は多くのドキュメントを読みました。ですので、参考になれば幸いです。シンプルなものだとおもいます。どんな助けでも大歓迎です

class Ping extends Thread {
   private Table table;
   private String text1 = "";

   public Ping(Table t)
   {
       table = t;
   }
   public void run() {

       for (int i = 0; i < 10; i++) {
           text1= table.getPing();
           System.out.println(text1);
   }
 }
}


class Pong extends Thread {
   private Table table;
   private String text1 = "";

   public Pong(Table t)
   {
       table = t;
   }
   public void run() {
       for (int i = 0; i < 10; i++) {
           text1= table.getPong();
           System.out.println(text1);   }
 }
}

class Table extends Thread {
    private Table table;
    private boolean pinged = false;

    public synchronized String getPong() {
        while (pinged == false) {
            try {
                //System.out.println("WAIT PONG");
                wait();
            } 
            catch (InterruptedException e) 
            { }
        }        
        pinged = false;

        notifyAll();
        String text = "pong";
        return text;
    }

    public synchronized String getPing() {
        while (pinged == true) {
            try {
                wait();
                //System.out.println("WAIT PING");
            } catch (InterruptedException e) { }
        }    
        pinged = true;
        notifyAll();
        String text = "ping";
        return text;
    }
}


public class PingPong {

    //private static final int WAIT_TIME = 200;

    public static void main(String args[]) {

        Table t = new Table();

        Pong pong = new Pong(t);

        Ping ping = new Ping(t);

        System.out.println("main: starting threads...");

        pong.start();
        ping.start();

        System.out.println("main: threads started, sleep a while " +
                           "and wait for termination of Ping and Pong"); 


        System.out.println("both threads terminated");
   }

}

それぞれの結果は異なりますが、奇妙なことに、繰り返しが発生します。

ping
pong
ping
ping
pong
pong
pong
ping
ping
ping
pong
pong
pong
ping
pong
ping
ping
pong
ping
pong
4

3 に答える 3

1

Table クラスでの同期 (ちなみに Thread を拡張する必要はありません) は、Ping スレッドと Pong スレッドが交互に文字列を取得することのみを保証します。文字列を交互に出力することを保証するものではありません。

たとえば、次のシーケンスが発生する可能性があります。

Ping gets its first ping, call it ping 1.
Ping prints ping 1.
Pong gets its first pong, call it pong 1.
Ping gets ping 2.
Ping prints ping 2.
Pong prints pong 1.
Pong gets pong 2.
Pong prints pong 2.
Ping gets ping 3.
Pong gets pong 3.
Pong prints pong 3.
Ping prints ping 3.

各スレッドは文字列の取得と出力を交互に行っており、2 つのスレッドは文字列を交互に取得していることに注意してください。ただし、一方のスレッドが文字列を取得してから文字列を出力するまでの間に、もう一方のスレッドが時間を取得する場合と取得しない場合があります。これにより、交互のシーケンスが印刷用に分割されます。この例では、出力は次のようになります。

ping
ping
pong
pong
pong
ping

これを修正したい場合は、文字列の取得と出力の両方を同じ同期ブロックに含める必要があります。そのブロックを System.out とテーブルで同期する必要がある場合があります。

于 2015-10-20T16:22:44.923 に答える
0

これを試してみてください。これがPing最初に実行されます。それはまたあなたにその反復を与えるでしょう

 class Ping extends Thread {
 private Table table;
 private String text1 = "";

 public Ping(Table t)
 {
   table = t;
 }
public void run() {

   for (int i = 0; i < 10; i++) {
       text1= table.getPing();
       System.out.println(i + " " + text1);
 }
 }
 }


class Pong extends Thread {
private Table table;
private String text1 = "";

public Pong(Table t)
{
    table = t;
 }

 public void run() {
   for (int i = 0; i < 10; i++) {
       text1= table.getPong();
       System.out.println(i + " " + text1);   }
  }
  }

class Table extends Thread {
private Table table;
private boolean pinged = false;

public synchronized String getPong() {
    while (pinged == false) {
        try {
            //System.out.println("WAIT PONG");
            wait();
        } 
        catch (InterruptedException e) 
        { }
    }        
    pinged = false;

    notifyAll();
    String text = "pong";
    return text;
}

public synchronized String getPing() {
    while (pinged == true) {
        try {
            wait();
            //System.out.println("WAIT PING");
        } catch (InterruptedException e) { }
    }    
    pinged = true;
    notifyAll();
    String text = "ping";
    return text;
   }
 }


    public class PingPong {

   //private static final int WAIT_TIME = 200;

   public static void main(String args[]) {

    Table t = new Table();

    Pong pong = new Pong(t);

    Ping ping = new Ping(t);

    System.out.println("main: starting threads...");

    ping.start();
    pong.start();

    System.out.println("main: threads started, sleep a while " +
                       "and wait for termination of Ping and Pong"); 


    System.out.println("both threads terminated");
   }

   }
于 2015-10-21T04:02:03.667 に答える