synchronization in Java

Java provides a way of creating threads and synchronizing their tasks using synchronized blocks. Synchronized blocks in Java are marked with the synchronized keyword. A synchronized block in Java is synchronized on some object. All synchronized blocks synchronize on the same object can only have one thread executing inside them at a time. All other threads attempting to enter the synchronized block are blocked until the thread inside the synchronized block exits the block.
* Using the synchronized keyword with a constructor is a syntax error. synchronizing constructors doesn't make sense,  because only the thread that creates an object should have access to it while it is being constructed.
```
import java.io.*;
import java.util.*;

class Sender{
    public void send(String msg) {
        System.out.println("Sending:"+msg);
    }
}

class SendThread extends Thread {
    private Sender sender;
    private String msg;
    
    SendThread(Sender sender, String msg) {
        this.sender = sender;
        this.msg = msg;
    }
    
    public void run() {
        synchronized(sender) {
            sender.send(msg);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Sender sender = new Sender();
        SendThread s1 = new SendThread(sender, "1"); s1.start();
        SendThread s2 = new SendThread(sender, "2"); s2.start();
        try {
            s1.join();
            s2.join();
        } catch(Exception e) {
            System.out.println("Interrupted");
        }
    }
}
```