For implementing threads do one of the following Extend from Thread class Or Implement Runnable interface Sample program #1 Public class MyThread extends Thread { Public MyThread() { } Public void run() { } }Thread class Public class client { Main() { MyThread obj=new MyThread() Obj.start(); // start() will call the run() method }//end main() }//client class Sample program #2 public class thread6 implements Runnable { int sum; Thread t; public thread6(int sum) { this.sum=sum; t=new Thread(this); t.start(); } public void run() { sum++; } } //Launch 100 threads each thread add 1 to a variable sum public class client6 { public static void main(String args[]) throws InterruptedException { int sum=0; for(int i=0;i<100;i++) { new thread6(sum++); } System.out.println("sum="+sum); } } Use wait() instead of suspend() to suspend a thread, Use notify() instead of resume() of resume a thread, Suspend() and resume() are known to be deadlock prone. The main thread should start first and should finish last, else the java program might hang. Sleep() method allows execution to switch to another thread. This might result in race conditions if the methods are not synchronized and the other threads are also calling the same methods. Synchronized void call(string msg) The word synchronized serializes access to that method, i.e. when one thread is calling a method then the state of all other threads is saved in a file.ser and this particular method is locked for use by the current thread executing on it. So by call to synchrinzed the current method will execute completely even if it has a sleep method inside it . Consider the following code:Public void call() { System.out.println(“[hello”); Sleep(2000); System.out.println(“]”); } The above method is not synchronized will print something like [hello[hello[hello…] This is because when sleep(2000) is called, then the control is passed to some other thread. i.e. the complete call() method is not called at once Consider the following synchronized code public synchronized void call() { System.out.println(“[hello”); Sleep(2000); System.out.println(“]”); } Herein the output will be [hello][hello][hello]… This is because the complete call() method is executed along with the sleep() method and then the control is transferred to some other thread. Synchronized block Public void run() { Thread obj_name=new Thread(); Synchronized (obj_name) { Obj_name.call(); } } Method Boolean isAlive() Final void join() throws InterruptedException Sleep() wait() Use Is the current thread alive This method waits until the thread on which it is called is terminated. Sleep() method allows execution to switch to another thread. This might result in race conditions if the methods are not synchronized and the other threads are also calling the same methods Tells the calling thread to give up the monitor and go to sleep until some other comments Used in inter-thread process communication notify() notifyAll() thread enters the same monitor and calls notify() Wakes up the first thread that called wait() on the same object. Wakes up all the threads that called wait() on the same object. The highest priority thread will run first. Used in inter-thread process communication Used in inter-thread process communication Threads 1) Process Threads In a multitasking operating system, each A thread shares the address space of program is run as a separate process the the program that created it Process switching has overhead minimal overhead with thread switching 2) Difference between Runnable (interface) and Thread (class) syntax Thread Runnable Thread class Runnable interface public class thread1 extends Thread public class runnableThread2 { implements Runnable private String name; { public thread1(String name) private String name; { public runnableThread2(String name) this.name=name; { } this.name=name; } public void run() { public void run() for(int i=0;i<5;i++) { { for(int i=0;i<5;i++) System.out.println("Thread name -{ >"+this.name); System.out.println("Thread name -} >"+this.name); } } } } } Main Thread public class mainThread1 { public static void main(String[] args) { thread1 t1=new thread1("ankur"); thread1 t2=new thread1("sandeep"); thread1 t3=new thread1("aditya"); t1.start(); t2.start(); t3.start(); } Main Thread public class mainThread2 { public static void main(String[] args) { runnableThread2 mt1=new runnableThread2("ankur"); runnableThread2 mt2=new runnableThread2("sandeep"); runnableThread2 mt3=new runnableThread2("priya"); } //Here the arguement to Thread class should be a Runnble object only, not even a Thread // class object will do. Thread t1=new Thread(mt1); Thread t2=new Thread(mt2); Thread t3=new Thread(mt3); t1.start(); t2.start(); t3.start(); // The blue portion indicate the difference block in creating threads from either extending from the Thread class or implementing from the Runnable interface. 3) Thread.yield() Use yield to prevent a thread from hogging the CPU public void run() { for (int i=0; i<8; i++) { System.out.println(internalName); Thread.yield(); } } 4) Thread.join() 5) Synchronized block Synchronized methods or code blocks LOCK an object Synchronization permits multiple threads to act concurrently without interfering with each other. any object may serve as the lock object eg. 1 public static void abs (int[ ] values) { synchronized (values) { for (int i=0; i<values.length; i++) { if (values[i] < 0) values[i] = -values[i]; } } } Eg.2 synchronized (<some object>) { statements; } some object to lock Variables cannot be synchronized. However you can control access if you: – declare variables private – provide accessor(getter and setter) methods. Synchronized and Non-Synchronized thread locking Synchronized objects can be accessed by threads only if it is not locked by any other thread, a non-synchronized thread can be accessed by more than one threads 1) There is atleast one thread always active in a program, this is the main thread. 2) There is one call stack maintained per thread. The main is the first method on the stack .As soon as we create a new thread, a new stack materializes and methods called from that thread run in a call stack that’s separate from the main() call stack. 3) The new call stack always is created when the run() method starts executing. 4) We can define and instantiate a thread in one of the following two ways. Method1: By extending the Thread class Public class MyThread extends Thread { Public static void main(String args[]) { MyThread t=new MyThread(); t.start(); } Public void run() { //do something } Method2: By implementing the Runnable interface. Public class MyThread { Public static void main(String args[]) { MyRunnable r=new MyRunnable(); Thread t1=new Thread1(r); Thread t2=new Thread1(r); Thread t3=new Thread1(r); T1.start(); T2.start(); T3.start(); } } Public class MyRunnable implements Runnable { Public void run() { //do something } } 5) Calling a run() method directly just means you are invoking a method from whatever thread is currently executing, and the run() method goes onto the current call stack rather than at the beginning of a new call stack. The following code does not start a new thread of execution. Runnable r=new Runnable(); r.run(); 6) When to use a thread class and when to use a Runnable interface a. Extending the Thread class is the easiest but it is not a good OOPs practice, because we cannot extend any other class if we extend the Thread class because java supports MultiLevel inheritance for classes and Muliple inheritance for interfaces. So if we implement the Runnable interface instead of a Thread class for our class then we can implement any no of interfaces and a class also. b. The only time it makes sense to extend the Thread class is when, we have a more specialized version of the Thread class. 7) to print the name of the currently executing thread Thread.currentThread().getName(); To set the name of the currently executing thread Public class NameThread { Public static void main(String args[]) { NameRunnable nr=new NameRunnable(); Thread t=new Thread(nr); t.setName(“FirstThread”); } } 8) Thread states a. New: The thread instance has been instantiated, but the start() method has not been invoked on the thread. b. Dead: When a thread completes its run() method, the thread ceases to be a thread of execution. Once a thread is dead it can never be restarted. c. Runnable: This is the state a thread is eligible to run(is in the Runnable pool) but the scheduler has not selected it to be in the running thread.. A thread first enters the runnable state when the start() method is invoked. When a thread is in the runnable state(in the Runnable pool) it is considered alive. The order in which runnable threads are chosen to run is not guaranteed. All threads in the Runnable state could be said to be in a pool, and any of them could be chosen to be executed, because which thread is selected from the Runnable pool of threads is dependent on the scheduler(OS part) and the JVM. d. Waiting / Blocked / Sleeping: The thread is alive but is currently not eligible to run. Although the thread is alive, it is not in the Runnable pool because it is waiting for some I/O resource or is sleeping(sleep() method called on the thread) or it is waiting(wait() method called on the thread). Some other waiting methods on the thread, namely resume(), suspend(), and stop() have been deprecated. e. Running:This is when the scheduler selects the thread from the Runnable pool to be the currently executing process. 9) Sleep(milliseconds) Sleeps the thread for said no of milliseconds. When a thread’s sleep expires and it wakes up it does not mean it will go to Running state, it only goes to the Runnable state. So the time specified in sleep() is the minimum duration in which the thread wont run, but it is not the exact duration in which the thread wont run. 10) Yield Yield() makes the currently running thread head back to runnable state to allow other threads of the same priority to get their turn. e.g. Thread.yield(). Will cause the currently executing thread to give up Running state and go to Runnable state. 11) Join It is a non static method. Lets one thread join onto the end of another thread. Imagine the following scenario. You are preparing for tomorrow's final examine and feel a little hungry. So, you give your younger brother ten bucks and ask him to buy a pizza for you. In this case, you are the main thread and your brother is a child thread. Once your order is given, both you and your brother are doing their job concurrently (i.e., studying and buying a pizza). Now, we have two cases to consider. First, your brother brings your pizza back and terminates while you are studying. In this case, you can stop studying and enjoy the pizza. Second, you finish your study early and sleep (i.e., your assigned job for today - study for tomorrow's final exam - is done) before the pizza is available. Of course, you cannot sleep; otherwise, you won't have a chance to eat the pizza. What you are going to do is to wait until your brother brings the pizza back. This is exactly the problem and solution we mentioned at the end of the previous section. Thread join is designed to solve this problem. A thread can execute a thread join to wait until the other thread terminates. In our case, you - the main thread - should execute a thread join waiting for your brother - a child thread - to terminate. In general, thread join is for a parent to join with one of its child threads. Thread join has the following activities, assuming that a parent thread P wants to join with one of its child threads C. When P executes a thread join in order to join with C, which is still running, P is suspended until C terminates. Once C terminates, P resumes. When P executes a thread join and C has already terminated, P continues as if no such thread join has ever executed (i.e., join has no effect). A parent thread may join with many child threads created by the parent. Or, a parent only join with some of its child threads, and ignore other child threads. In this case, those child threads that are ignored by the parent will be terminated when the parent terminates. 12) Thread Priorities Thread Priorities are between 1 and 10 with 10 being the highest. So the currently running thread has a priority equal than or greater than the highest priority thread in the Runnable pool of threads. e.g. FooRunnable r=new FooRunnable(); Thread t=new Thread(r); t.setPriority(8); t.start(); The JVM will never change the priority of a thread. The default priority is 5. Thread.MIN_PRIORITY (1) Thread.NORM_PRIORITY(5) Thread.MAX_PRIORITY(10) 13) Thread Groups 14) notify() / notifyAll()and wait If threads want to communicate about the status of their locks then they can do so with the three methods of the java.lang.Object class namely notify, notifyAll and wait. These methods can only be called from within a synchronized context. A thread cant invoke a wait or notify method on an object unless it owns that objects lock. //Without wait and notify public class ThreadA { public static void main(String args[]) { ThreadB b=new ThreadB(); b.start(); synchronized(b) { try { System.out.println("waiting for thread b to complete..."); //b.wait(); System.out.println("after b"); } catch(Exception e){ } } } } class ThreadB extends Thread { int total; public void run() { synchronized(this){ for(int i=0;i<10;i++) { total+=i; System.out.println(total); } // notify(); } } } Output: waiting for thread b to complete... after b 0 1 3 6 10 15 21 28 36 45 //With notify and wait() public class ThreadA { public static void main(String args[]) { ThreadB b=new ThreadB(); b.start(); synchronized(b) { try { System.out.println("waiting for thread b to complete..."); b.wait(); System.out.println("after b"); } catch(InterruptedException e){ } } } } class ThreadB extends Thread { int total; public void run() { synchronized(this){ for(int i=0;i<10;i++) { total+=i; System.out.println(total); } notify(); } } } Output waiting for thread b to complete... 0 1 3 6 10 15 21 28 36 45 after b 15) Synchronize Only methods can be synchronized, not variables Each object has just one lock, each thread however can have more than one lock e.g a thread can enter a synchronized method, thus acquiring a lock and then immediately invoke a synchronized method on a different object thus acquiring that lock as well. As the stack unweilds the lock on the top of the stack is released first. A class have have synchronized and unsynchronized methods. if two methods are synchronized in a class only one thread can be accessing one of the two methods. In other words once a thread acquires the lock on an object no other thread can enter any of the synchronized methods in that class(for that object). If a class has both synchronized and non-synchronized methods, multiple threads can still access the non-synchronized methods of the class. if a thread goes to sleep , it takes its locks with it. you can synchronize a block of code rather than a method. Synchronization does hurt concurrency. We don’t want to synchronize any more code than is necessary to protect your data. e.g. class syncTest { Public void doStuff() { System.out.println(“not synchronized”); Synchronized(this); System.out.println(“synchronized”); } } } When you synchronize a method, the object used to make the method call is the object whose lock must be acquired. In case of a synchronized block, we have to specify which objects lock you want to use as a lock. This gives us the ability to have more than one lock for code synchronization within a single object. e.g. void someOperation(Foo foo) { int sum = 0; synchronized(foo) { // acquire foo lock sum += foo.value; } // release foo lock