简单的乒乓Java线程

时间:2015-10-20 13:38:51

标签: java multithreading operating-system java-threads

我正在尝试制作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

3 个答案:

答案 0 :(得分: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上同步。

答案 1 :(得分: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");
   }

   }

答案 2 :(得分: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();
    }

}