title: What is the difference between Thread.join and Synchronized?
body: <p>I am confused when to use <code>Thread.join()</code> and when to use <code>synchronization</code> in multi threading application. </p>
  
  <p>According to me, both of them block or wait for the execution to be done by some other thread. <br>
  This example has to output 10 A's , 10 B's &amp; 10 C's in sequential pattern one after other like :</p>
  
  <pre><code>1  : A
  2  : A
  3  : A
  4  : A
  5  : A
  6  : A
  7  : A
  8  : A
  9  : A
  10 : A
  1  : B
  2  : B
  3  : B
  4  : B
  5  : B
  6  : B
  7  : B
  8  : B
  9  : B
  10 : B
  1  : C
  2  : C
  3  : C
  4  : C
  5  : C
  6  : C
  7  : C
  8  : C
  9  : C
  10 : C
  ----ProGraM ENDS----
  </code></pre>
  
  <p><strong>Example starts here</strong></p>
  
  <pre><code>class SyncTest extends Thread 
  {   
      StringBuffer sb;
  
      public SyncTest(StringBuffer sb) 
      {
          this.sb = sb;   
      }
  
      public void run()
      {
          synchronized(sb) 
          {
              for(int i=1;i&lt;=10;i++){
                  System.out.println(i+" : "+sb.charAt(0));
              }
              sb.setCharAt(0, (char) (sb.charAt(0)+1));
          }
      }
  
      public static void main(String [] args) throws InterruptedException
      {
          StringBuffer sb = new StringBuffer("A");
          Thread t1=new SyncTest(sb);
          Thread t2=new SyncTest(sb);
          Thread t3=new SyncTest(sb);
  
          t1.start();
  
          t2.start();
  
          t3.start();
  
          Thread.sleep(1000);
  
          System.out.println("----ProGraM ENDS----");
      }
  }
  </code></pre>
  
  <p>Here, output turns out to be 10 A's followed by 10 B's followed by 10 C's in a sequential order. But I can also use <code>Thread.join</code> instead of <code>synchronized</code> block to get the same output like this:</p>
  
  <pre><code>public void run()
      {
          //removed synchronized statement...
  
              for(int i=1;i&lt;=10;i++){
                  System.out.println(i+" : "+sb.charAt(0));
              }
              sb.setCharAt(0, (char) (sb.charAt(0)+1));
  
      }
  
      public static void main(String [] args) throws InterruptedException
      {
          StringBuffer sb = new StringBuffer("A");
          Thread t1=new SyncTest(sb);
          Thread t2=new SyncTest(sb);
          Thread t3=new SyncTest(sb);
  
          t1.start();
          t1.join();
          t2.start(); // wait for t1 to complete
          t2.join();
          t3.start(); // wait for t2 to complete
          t3.join(); 
  
                       // wait for t3 to complete
          System.out.println("----ProGraM ENDS----");
      }
  </code></pre>
  
  <p>Can anyone clear my confusion on usage of these 2 techniques i.e. when to use <code>Thread.join</code> and when to use <code>synchronization</code> in Multi-threading on Java.</p>