class ChatExample{ boolean flag = false; public synchronized void Question(String msg){ if(flag){ try{ wait(); }catch(InterruptedException ex){ e.printStackTrace(); } } System.out.println(msg); flag = true; notify(); } public synchronized void Answer(String msg){ if(!flag){ try{ wait(); }catch(InterruptedException ex){ e.printStackTrace(); } } System.out.println(msg); flag = false; notify(); } } class T1 implements Runnable{ ChatExample m; String[] s1 = {"Hi, How are you, I am fine"}; public T1(ChatExample m1){ this.m = m1; new Thread(this, "Question").start(); } public void run(){ for(int i = 0; i< s1.length; i++){ m.Question(s1[i]); } } } class T2 implements Runnable{ ChatExample m; String[] s2 = {"Hi, I am good, What about you, Great"}; public T2(ChatExample m2){ this.m = m2; new Thread(this, "Answer").start(); } public void run(){ for(int i = 0; i< s2.length; i++){ m.Answer(s2[i]); } } } public class ThreadTest{ public static void main(String args[]){ ChatExample ce = new ChatExample(); new T1(ce); new T2(ce); } }