Thread: Thread. Even If You Don't Create Any New Threads in Your Program, Threads Are Back
Thread: Thread. Even If You Don't Create Any New Threads in Your Program, Threads Are Back
Thread: Thread. Even If You Don't Create Any New Threads in Your Program, Threads Are Back
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{
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
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:-
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); }}}
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
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
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).