1

我正在尝试制作 2 个线程,一个 Ping 和一个 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.

请注意,每个线程在获取字符串和打印字符串之间交替进行,并且两个线程以交替顺序获取字符串。但是,在一个线程获取字符串和打印字符串之间,另一个线程可能会或可能不会获得时间。这导致交替序列被分解以进行打印,在我们的示例中,输出为:

ping
ping
pong
pong
pong
ping

如果你想解决这个问题,你需要在同一个同步块中包含获取字符串和打印它,并且你可能需要该块在 System.out 和 Table 上同步。

于 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 回答
0

在这种情况下使用同步队列应该简单有效。

import java.util.concurrent.SynchronousQueue;

public class PingPongPattern {



private SynchronousQueue<Integer> q = new SynchronousQueue<Integer>();
    private Thread t1 = new Thread() {

        @Override
        public void run() {
            while (true) {

                // TODO Auto-generated method stub
                super.run();
                try {

                    System.out.println("Ping");
                    q.put(1);
                    q.put(2);
                } catch (Exception e) {

                }
            }
        }

    };

    private Thread t2 = new Thread() {

        @Override
        public void run() {

            while (true) {
                // TODO Auto-generated method stub
                super.run();
                try {
                    q.take();
                    System.out.println("Pong");
                    q.take();

                } catch (Exception e) {

                }

            }

        }

    };

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        PingPongPattern p = new PingPongPattern();
        p.t1.start();
        p.t2.start();
    }

}
于 2017-04-04T15:28:28.543 回答