2015-10-20 81 views
1

我正在嘗試使2個線程一個Ping和一個Pong。這個想法是Ping應該始終執行。我正在使用同步方法。我不確定這裏的代碼有什麼問題。它看起來像它應該工作。我已經閱讀了很多文檔。所以如果你有任何你認爲會有幫助的東西,我會很樂意閱讀它。我相信這很簡單。任何幫助表示讚賞簡單的Ping Pong Java線程

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 
+1

看來你未來的影響[同步和的System.out.println(http://stackoverflow.com/questions/9459657/synchronization-and-system-out-println) – alex2410

回答

1

在你的表類的同步 - 它的方式並不需要擴展Thread - 只保證平安和安邦線得到他們的字符串以交替的方式。它不能保證他們以交替的方式打印字符串。

例如,可能會出現以下順序:

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 

如果要解決這個問題,就需要包括獲得一個字符串,並在同一個synchronized塊打印出來,並且您可能需要該塊才能在System.out和Table上同步。

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"); 
    } 

    } 
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(); 
    } 

}