class Mythread implements Runnable { int id; public Mythread(int x) { id=x; } public void run() { while (true) { System.out.println("I am Mythread id "); System.out.print(id); } } }//Mythread public class threads { public static void main(String[] av) throws Exception { Thread t1 = new Thread(new Mythread(1)); Thread t2 = new Thread(new Mythread(2)); t1.start(); // calls .run() as concurrent thread t2.start(); t1.join(); // wait for t1 to finish (never in this case) t2.join(); } } /* Concurrent programming can be very difficult. To simplify matters, Java has provided some built-in data structures that are synchronized: this means two thread writing to the same memory address will syncrhonize to avoid undoing eachother's work. Unsynchronized Synchronized ArrayList Vector Hashmap Hashtable HashSet TreeSet (red-black tree) ? PriorityQueue (heap) PriorityBlockingQueue ... Using the synchronized structures guarantees thread safety but not necessarily the most efficient code, since in general we should minimize the use of synchronization. Sophisticated concurrent programmers will need to be able to create their own synchronization mechanisms such as monitors and semaphores. Java provides a keyword that can be placed before methods, such as public synchronized int f(...) Given object n, only one synchronized method of n can be called concurrently. Using this feature is more subtle than it may appear however. For example, people would often put synchronized methods inside thread (Runnable) classes, which seldom synchrnizes anything (except between mehthods on the same instance of the thread class). n.f(..) and m.f(..) would not be synchronized if n and m are different instances. Synchronized methods are used to construct Hoare Monitors, and you need to understand this theoretical concept in order to use them correctly. */