Sunteți pe pagina 1din 28

Thread

In Java, "thread" means two different things:


■ An instance of class java.lang.Thread
■ A thread of execution

An instance of Thread is just…an object. Like any other object in Java, it has
variables and methods, and lives and dies on the heap. But a thread of execution is
an individual process (a "lightweight" process) that has its own call stack. In Java,
there is one thread per call stack—or, to think of it in reverse, one call stack per
thread. Even if you don't create any new threads in your program, threads are back
there running.

Making a Thread
A thread in Java begins as an instance of java.lang.Thread. You'll find methods
in the Thread class for managing threads including creating, starting, and pausing
them.
So if the work you want done is the job, the one doing the work
(actually executing the job code) is the thread. And the job always starts from a
run() method as follows:
public void run() {
// your job code goes here
}

 You always write the code that needs to be run in a separate thread in a run()
method.
Main Thread:-
public class CurrentThread{

public static void main(String[] args) {


Thread t = Thread.currentThread();
System.out.println("Current thread: " + t);
// change the name of the thread
t.setName("My Thread");
System.out.println("After name change: " + t);
}
}
Output:- Current thread: Thread[main,5,main]
After name change: Thread[My Thread,5,main]
This displays, in order: the name of the thread, its priority, and the name of its group. By
default, the name of the main thread is main. Its priority is 5, which is the default value,
and main is also the name of the group of threads to which this thread belongs.
A thread group is a data structure that controls the state of a collection of threads as a
whole. This process is managed by the particular run-time environment.
Sleep a thread:-
public class Student {
public static void main(String[] args) {
for (int n = 1; n <= 5; n++) {
System.out.println(n);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();}}}}
The sleep( )method causes the thread from which it is called to suspend execution for the specified
period of milliseconds. Its general form is shown here:
static void sleep(long milliseconds) throws InterruptedException.
This second form is useful only in environments that allow timing periods as short as nanoseconds. 

You can define and instantiate a thread in one of two ways:


■ Extend the java.lang.Thread class.
■ Implement the Runnable interface.
Note:- In the real world you're much more likely to implement Runnable than extend Thread.
Extending the Thread class is the easiest, but it's usually not a good OO practice. So you
should design a class that implements the Runnable interface, which also leaves your
class free to extend some other class.
Commonly used methods of Thread class:

1.public void run(): is used to perform action for a thread.


2.public void start(): starts the execution of the thread.JVM calls the run()
method on the thread.
3.public void sleep(long miliseconds): Causes the currently executing
thread to sleep (temporarily cease execution) for the specified number of
milliseconds.
4.public void join(): waits for a thread to die.
5.public void join(long miliseconds): waits for a thread to die for the
specified miliseconds.
6.public int getPriority(): returns the priority of the thread.
7.public int setPriority(int priority): changes the priority of the thread.
8.public String getName(): returns the name of the thread.
9.public void setName(String name): changes the name of the thread.
10.public Thread currentThread(): returns the reference of currently
executing thread.
11.public int getId(): returns the id of the thread.
12.public Thread.State getState(): returns the state of the thread.
13.public boolean isAlive(): tests if the thread is alive.
1.public void yield(): causes the currently executing thread
object to temporarily pause and allow other threads to execute.
2.public void suspend(): is used to suspend the
thread(depricated).
3.public void resume(): is used to resume the suspended
thread(depricated).
4.public void stop(): is used to stop the thread(depricated).
5.public boolean isDaemon(): tests if the thread is a daemon
thread.
6.public void setDaemon(boolean b): marks the thread as
daemon or user thread.
7.public void interrupt(): interrupts the thread.
8.public boolean isInterrupted(): tests if the thread has been
interrupted.
9.public static boolean interrupted(): tests if the current
thread has been interrupted.
Here is not thread this is simple sequential programming.
public class NotThread{
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
r.run();
NotThread st=new NotThread();
st.show();
}
void show(){
for (int n = 1; n <= 5; n++) {
System.out.println("main Show");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}}}}
class MyRunnable{
public void run() {
for (int n = 1; n <= 5; n++) {
System.out.println(n);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}}}}
Note:-public class Thread extends Object implements Runnable
Extending java.lang.Thread
The simplest way to define code to run in a separate thread is to
■ Extend the java.lang.Thread class.
■ Override the run() method.
It looks like this:
class MyThread extends Thread {
public void run() {
System.out.println("Important job running in MyThread");
}
}
Note:-Thread starts after calling start method of Thread class.
public class ThreadWithExtends{
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
r.start();
ThreadWithExtends st=new ThreadWithExtends();
st.show();
}
void show(){
for (int n = 1; n <= 5; n++) {
System.out.println("main Show");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}}}
class MyRunnable extends Thread{
public void run() {
for (int n = 1; n <= 5; n++) {
System.out.println(n);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}}}
}
Every thread has its own separate path to execute the code run below.
public class ThreadSeperatePath{
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
r.start();
r.start();
ThreadSeperatePath st=new ThreadSeperatePath();
st.show();
}
void show(){
for (int n = 1; n <= 5; n++) {
System.out.println("main Show");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}}}}
class MyRunnable extends Thread{
public void run() {
for (int n = 1; n <= 5; n++) {
System.out.println(n);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();}}}}
Implementing java.lang.Runnable
Implementing the Runnable interface gives you a way to extend any class you like,
but still define behavior that will be run by a separate thread. It looks like this:
class MyRunnable implements Runnable {
public void run() {
System.out.println("Important job running in MyRunnable");
}
}
Note:- If you implement Runnable you still need a Thread instance.So Thread is the
"worker," and the Runnable is the "job" to be done.
First, you instantiate your Runnable class:
MyRunnable r = new MyRunnable();
Next, you get yourself an instance of java.lang.Thread (somebody has to run your
job…), and you give it your job!
Thread t = new Thread(r); // Pass your Runnable to the Thread
If you create a thread using the no-arg constructor, the thread will call its own run()

But when you use Runnable, you need to tell the new thread to
use your run()method rather than its own. The Runnable you pass to the Thread
constructor is called the target or the target Runnable.
You can pass a single Runnable instance to multiple Thread objects, so that the
same Runnable becomes the target of multiple threads, as follows:
public class TestThreads {
public static void main (String [] args) {
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
Thread t3 = new Thread(r);}}
The constructors we care about are
■ Thread()
■ Thread(Runnable target)
■ Thread(Runnable target, String name)
■ Thread(String name)
 Thread t = new Thread(); // no-args constructor
System.out.println("Current thread: " + t); // Thread[Thread-0,5,main]
 Thread t = new Thread(“My Thread”); // one string parametric constructor

 MyRunnable r = new MyRunnable();


Thread t1 = new Thread(r); // Thread(Runnable target)

 MyRunnable r = new MyRunnable();


Thread t1 = new Thread(r,”My Thread”); // Thread(Runnable target)
Example:-
class MyRunnable implements Runnable {
public void run() {
for(int x = 1; x < 6; x++) {
System.out.println("Runnable running");}}}
public class TestThreads {
public static void main (String [] args) {
MyRunnable r = new FooRunnable();
Thread t = new Thread(r);
t.start();}}
Thread States and Transitions:-
Thread States:-
A thread can be only in one of five states:-
■ New This is the state the thread is in after the Thread instance has been
created, but the start() method has not been invoked on the thread. At this point, the
thread is considered not alive.
■ Runnable This is the state a thread is in when it's eligible to run, but the
scheduler has not selected it to be the running thread. A thread first enters
the runnable state when the start() method is invoked, but a thread can
also return to the runnable state after either running or coming back from a
blocked, waiting, or sleeping state. When the thread is in the runnable state,
it is considered alive.
■ Running This is the state a thread is in when the thread scheduler selects it (from the runnable
pool) to be the currently executing process. A thread can transition out of a running state for several
reasons.
■ Waiting/blocked/sleeping This is the state a thread is in when it's not
eligible to run.So this is really three states combined into one,
but they all have one thing in common: the thread is still alive, but is
currently not eligible to run. In other words, it is not runnable, but it might
return to a runnable state later if a particular event occurs.
■ Dead A thread is considered dead when its run() method completes. Once a thread is dead, it
can never be brought back to life. If you invoke start() on a dead Thread
instance, you'll get a runtime (not compiler) exception.
Thread Life Cycle:-
Preventing Thread Execution:-
■ Sleeping
■ Waiting
■ Blocked because it needs an object's lock
Sleeping:-
On this state, the thread is still alive but it is not runnable, it might be return to runnable state later, if
a particular event occurs. On this state a thread sleeps for a specified amount of time. You can use the
method sleep( ) to stop the running state of a thread.
   static void sleep(long millisecond) throws InterruptedException
try {
Thread.sleep(5*60*1000); // Sleep for 5 minutes
} catch (InterruptedException ex) { }

Remember that sleep() is a static method, so don't be fooled into thinking that
one thread can put another thread to sleep.
public class SleepIsStatic{
public static void main(String[] args) {
MyRunnable r1 = new MyRunnable();MyRunnable r2 = new MyRunnable();MyRunnable r3 = new
MyRunnable();MyRunnable r4 = new MyRunnable();
r2.start();r3.start();r4.start();r1.start();SleepIsStatic st = new SleepIsStatic();st.show();}
void show() {for (int n = 1; n <= 5; n++) {System.out.println("main Show");
try {
Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}
class MyRunnable extends Thread {public void run() {for (int n = 1; n <= 5; n++) {
System.out.println(n);try {Thread.sleep(2000);} catch (InterruptedException e) {
e.printStackTrace();}}}}
The join() method:-
The join() method waits for a thread to die.
public void join()throws InterruptedException
public void join(long milliseconds)throws InterruptedException
Waits at most milliseconds for this thread to die. A timeout of 0 means to wait forever.
public class JoiningThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println(e);
}
System.out.println(Thread.currentThread().getName()+":->"+i);}}
public static void main(String args[]) {
JoiningThread t1 = new JoiningThread ();
JoiningThread t2 = new JoiningThread ();
JoiningThread t3 = new JoiningThread ();
// set thread names
t1.setName("T1");t2.setName("T2");t3.setName("T3");
t1.start();
try {
t1.join();// first t1 will complete
} catch (Exception e) {System.out.println(e);}
t2.start();
t3.start();}}
Synchronizing Code:-

What happens when two different threads have access


to a single instance of a class, and both threads invoke methods on that object…and
those methods modify the state of the object?
This problem is known as a "race condition," where multiple threads can access
the same resource (typically an object's instance variables), and can produce
corrupted data if one thread "races in".
Example:-
public class RaceCondition extends Thread {
static int bal = 10;
public static void main(String[] args) {
RaceCondition rs = new RaceCondition ();
Thread t1 = new Thread(rs);
Thread t2 = new Thread(rs);t1.setName("T1");t2.setName("T2");t1.start();t2.start();}
public void checkBalance() {try {System.out.println("Balance for "
+ Thread.currentThread().getName() + "=" + bal);Thread.sleep(2000);withdrawal();} catch (Exception
ex) {}}
public void withdrawal() {
if (bal >= 10) {
System.out.println(Thread.currentThread().getName()
+ " is able to withdrawal.");bal -= 5;
System.out.println("Balance after withdrawal by "+ Thread.currentThread().getName() + "=" + bal);}
else {System.out.println(Thread.currentThread().getName()
+ " is not able to withdrawal.");System.out.println("Insufficent balance for "
+ Thread.currentThread().getName() + "=" + bal);}}
@Override public void run() {checkBalance();}}
To solve the race condition issue we have to use synchronization so apply the synchronize
keyword before checkBalance method and see output.

Synchronized Instance Methods


public synchronized void add(int value){
// do something;
}

Synchronized Blocks in Instance Methods


You do not have to synchronize a whole method. Sometimes it is preferable to synchronize only part of
a method. Java synchronized blocks inside methods makes this possible.
public void add(int value){
synchronized(this){
// do something;
}}

Synchronized Static Methods


Static methods are marked as synchronized just like instance methods using the synchronized
keyword. Here is a Java synchronized static method example:

public static synchronized void add(int value){


// do something;
}
Synchronized Instance Method:-
Lock only particular one specific object or current object.

Synchronized static Method:-


A static method is associated with a class, not an object. In this case, the thread acquires the intrinsic
lock for the Class object associated with the class.

public class LockOnlyOneObject extends Thread {


static int bal = 10;
public static void main(String[] args) {
LockOnlyOneObject s1 = new LockOnlyOneObject ();
LockOnlyOneObject s2 = new LockOnlyOneObject ();
Thread t1 = new Thread(s1);// if t1 and t2 will work for same instance s1 or s2 it will working
//fine.Thread t2 = new Thread(s2);t1.setName("T1");t2.setName("T2");t1.start();t2.start();}
public synchronized void checkBalance() {try {System.out.println("Balance for "+
Thread.currentThread().getName() + "=" + bal);Thread.sleep(2000);withdrawal();} catch
(Exceptionex) {}}public void withdrawal() {if (bal >= 10)
{System.out.println(Thread.currentThread().getName()+ " is able to withdrawal.");bal -=
5;System.out.println("Balance after withdrawal by "+ Thread.currentThread().getName() + "=" + bal);}
else {System.out.println(Thread.currentThread().getName()+ " is not able to withdrawal.");
System.out.println("Insufficent balance for "+ Thread.currentThread().getName() + "=" + bal);}}
@Overridepublic void run() {checkBalance();}}

Note:- apply static keyword with checkBalance() method and see the result it’ll lock of all
objects of Class’s objects associated with this class.
wait, notify and notifyAll:-
The Object class in java contains three final methods that allows threads to communicate about the
lock status of a resource. These methods are wait(), notify() and notifyAll().

wait
Object wait methods has three variance, one which waits indefinitely for any other thread to call notify
or notifyAll method on the object to wake up the current thread. Other two variances puts the current
thread in wait for specific amount of time before they wake up.

notify
notify method wakes up only one thread waiting on the object and that thread starts execution. So if
there are multiple threads waiting for an object, this method will wake up only one of them. The choice
of the thread to wake depends on the OS implementation of thread management.

notifyAll
notifyAll method wakes up all the threads waiting on the object, although which one will process first
depends on the OS implementation.

Note:-
The current thread which invokes these methods on any object should have the object monitor else it
throws java.lang.IllegalMonitorStateException exception.
Means wait(), notify(), notifyAll() must be called inside a synchronized method/block.
Producer Consumer Problem:-
public class Student1 extends Thread {
public static void main(String[] args) {
Shared s = new Shared();new Producer(s).start();new Consumer(s).start();}}

class Shared { private char c; private boolean writeable = true; synchronized void setSharedChar(char c) {
while (!writeable)try { wait(); } catch (InterruptedException e) {} this.c = c; writeable = false;notify(); }
synchronized char getSharedChar() { while (writeable)try {wait(); } catch (InterruptedException e) {
} writeable = true;notify(); return c; }}

class Producer extends Thread { private Shared s; Producer(Shared s) { this.s = s; } public void run() {
System.out.println("Starting producer thread."); for (char ch = 'A'; ch <= 'D'; ch++) { try
{ Thread.sleep(2000); } catch (InterruptedException e) { }System.out.println(ch + " produced by
producer."); s.setSharedChar(ch); }}}

class Consumer extends Thread { private Shared s;Consumer(Shared s) { this.s = s;


}public void run() { System.out.println("Starting consumer thread."); char ch; do {try {
Thread.sleep(2000);} catch (InterruptedException e) { }
ch = s.getSharedChar();
System.out.println(ch + " consumed by consumer.");
} while (ch != 'Z');
}
}
Daemon Thread in Java

Daemon thread in java is a service provider thread that provides


services to the user thread. Its life depend on the mercy of user threads
i.e. when all the user threads dies, JVM terminates this thread
automatically.

Points to remember for Daemon Thread in Java

•It provides services to user threads for background supporting tasks. It


has no role in life than to serve user threads.
•Its life depends on user threads.
•It is a low priority thread.
Methods for Daemon thread by Thread class

No. Method Description

1) public void setDaemon(boolean status) is used to mark the current


thread as daemon thread or
user thread.

2) public boolean isDaemon() is used to check that current is


daemon.
Simple example of Daemon thread in java

File: MyThread.java

public class TestDaemonThread1 extends Thread{  
 public void run(){  
  if(Thread.currentThread().isDaemon()){//checking for daemon thread  
   System.out.println("daemon thread work");  
  }  

  else{  
  System.out.println("user thread work");  
 }  
 }  
public static void main(String[] args){  
  TestDaemonThread1 t1=new TestDaemonThread1();//creating
 thread  
  TestDaemonThread1 t2=new TestDaemonThread1();  
  TestDaemonThread1 t3=new TestDaemonThread1();  
  
  t1.setDaemon(true);//now t1 is daemon thread  
    
  t1.start();//starting threads  
  t2.start();  
  t3.start();  
 }  
}  

Output

daemon thread work


user thread work
user thread work
If you want to make a user thread as Daemon, it must not be started otherwise it
will throw IllegalThreadStateException.

class TestDaemonThread2 extends Thread{  
 public void run(){  
  System.out.println("Name: "+Thread.currentThread().getName());  
  System.out.println("Daemon: "+Thread.currentThread().isDaemon());  
 }  
  
 public static void main(String[] args){  
  TestDaemonThread2 t1=new TestDaemonThread2();  
  TestDaemonThread2 t2=new TestDaemonThread2();  
  t1.start();  
  t1.setDaemon(true);//will throw exception here  
  t2.start();  
 }  
}  
java.lang

Class ThreadLocal<T>

java.lang.Object java.lang.ThreadLocal<T>
Direct Known Subclasses:
InheritableThreadLocal

public class ThreadLocal<T>extends Object

ThreadLocal instances are typically private static fields in classes that wish to associate state with
a thread (e.g., a user ID or Transaction ID).
What is Thread Local?
Thread Local can be considered as a scope of access, like a request scope or session scope.
It’s a thread scope. You can set any object in Thread Local and this object will be global and
local to the specific thread which is accessing this object. Global and local!!? Let me
explain:
•Values stored in Thread Local are global to the thread, meaning that they can be accessed
from anywhere inside that thread. If a thread calls methods from several classes, then all
the methods can see the Thread Local variable set by other methods (because they are
executing in same thread). The value need not be passed explicitly. It’s like how you use
global variables.
•Values stored in Thread Local are local to the thread, meaning that each thread will have
it’s own Thread Local variable. One thread can not access/modify other thread’s Thread
Local variables.
When to use Thread Local?
Consider you have a Servlet which calls some business methods. You have a requirement to generate a
unique transaction id for each and every request this servlet process and you need to pass this
transaction id to the business methods, for logging purpose. One solution would be passing this
transaction id as a parameter to all the business methods. But this is not a good solution as the code is
redundant and unnecessary.
To solve that, you can use Thread Local. You can generate a transaction id (either in servlet or better
in a filter) and set it in the Thread Local. After this, what ever the business method, that this servlet
calls, can access the transaction id from the thread local.
This servlet might be servicing more that one request at a time. Since each request is processed in
separate thread, the transaction id will be unique to each thread (local) and will be accessible from all
over the thread’s execution (global).

How to use Thread Local?


Java provides an ThreadLocal object using which you can set/get thread scoped variables.
public class Test extends Thread {
public static void main(String args[]) {
Thread threadOne = new Test();
threadOne.setName("T1");threadOne.start();Thread threadTwo = new Test();
threadTwo.setName("T2");threadTwo.start();
}@Override public void run() {
// sample code to simulate transaction id
Context context = new Context();context.setTransactionId(getName());
// set the context object in thread local to access it somewhere else
MyThreadLocal.set(context);
/* note that we are not explicitly passing the transaction id */
new BusinessService().businessMethod();MyThreadLocal.unset();}}
class Context {private String tra nsactionId = null;
public String getTransactionId() {
return transactionId;}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;}}
class MyThreadLocal {
public static final ThreadLocal<Context> userThreadLocal = new ThreadLocal<Context>();
public static void set(Context user) {userThreadLocal.set(user);}
public static void unset() {userThreadLocal.remove();}
public static Context get() {return userThreadLocal.get();}}
class BusinessService {public void businessMethod() {
// get the context from thread local
Context context = MyThreadLocal.get();System.out.println(context.getTransactionId()); }}
Note:-protected  T initialValue()
          Returns the current thread's "initial value" for this thread-local variable.

S-ar putea să vă placă și