Daemon, Synchronization, Inter thread and Dead Lock in Multithreading - Java

Daemon thread in java is a service provider thread that provides services to the user thread. Its life depend on the user threads i.e. when all the user threads dies, JVM terminates this thread automatically.
There are many java daemon threads running automatically e.g. gc, finalizer etc.
You can see all the detail by typing the jconsole in the command prompt. The jconsole tool provides information about the loaded classes, memory usage, running threads etc.
Why JVM terminates the daemon thread if there is no user thread?
The sole purpose of the daemon thread is that it provides services to user thread for background supporting task. If there is no user thread, why should JVM keep running this thread. That is why JVM terminates the daemon thread if there is no user thread
Methods:
  • public void setDaemon(boolean status)
  • public boolean isDaemon()
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();
 }
 }

Synchronization:

Synchronizer is a modifier applicable only for methods and blocks but not for classes/variables
  • If multiple threads are trying to operate on the same java object then there may be chance of data inconsistency problem. To overcome this problem we should go for synchronizer necessarily.
  • If a method/block declared as synchronizer then only one thread is allowed to execute that method block, so that data inconsistency problem will be resolved.
  • The main advantage synchronized keyword is, we can resolve data inconsistency problem but the disadvantage is, it increases waiting time of threadsand creates performance problem. Hence if there is no specific requirement then its not recommended to use.
  • Internally Synchronization concept is implemented by using lock. Every object has a unique lock whenever we are using synchronized keyword only then lock concept come to picture.
  • If a thread wants to execute synchronized method on given object , basically it has to get lock of that object. Once thread gets lock, then its allowed to execute any synchronized method on that object. Once a method execution completes automatically thread release lock. At acquiring and releasing lock internally taken care by JVM not the user.
While thread executing synchronized method on the given object, the remaining threads are not allowed to execute any synchronized method simultaneously on the same object. But remaining threads are allowed to execute non-synchronized method simultaneously
Class x {
synch m1()
synch m2() 
m3() 
}
class Display{ 
public static synchronized void wish(String name) { for(int i=0; i<3; i++) { System.out.println("Hello");
 }
try{ 
Thread.sleep(2000);
 }
catch(InterruptedException e)
{ }
System.out.println(name); 
Display d= new Display();
 d.wish("Dhoni"); 
}
 }
class MyThread extends Thread 
{ 
Display d; 
String name; 
MyThread(Display d, String name) 
{
 this.d=d; this.name=name; 
}
public void run() 
{ 
d.wish(name);
 } 
} 
public class Demo1 
{ 
public static void main(String[] args)
 {
 Display d=new Display(); 
MyThread t= new MyThread(d,"K L Rahul");
 t.start();
 MyThread t1= new MyThread(d,"ABD");
t1.start();
 }
}

It is a set of instructions, it able to allow only one thread at a time to execute instructions, it will not allow more than one thread at a time, it will allow other threads after completion of the present thread execution.

Even though wish method is synchronized we will get irregular output because threads are operating on different java objects

Conclusion: If multiple threads are operation on same java object, then synch is required else not

Synchronized block:

It is a set of instructions, it able to allow only one thread at a time to execute instructions, it will not allow more than one thread at a time, it will allow other threads after completion of the present thread execution.
Syntax: 
synchronized(Object o)
 {
  ----- ----- 
}
class A {
void m1() 
{
String thread_Name=Thread.currentThread().getName(); 
System.out.println("Before Synchronized Block :"+thread_Name);
 synchronized(this)
 {for(int i=0;i<10;i++)
 {
String thread_Name1=Thread.currentThread().getName(); 
System.out.println("Inside Synchronized Block :"+thread_Name1); 
}
}
}
}
class MyThread1 extends Thread {A a; MyThread1(A a) 
{
this.a=a;
 }
public void run()
 {
a.m1(); 
}
}
class MyThread2 extends Thread {A a; MyThread2(A a) 
{
this.a=a; 
}
public void run()
 {
a.m1(); 
}
}
class MyThread3 extends Thread 
{
A a; MyThread3(A a) 
{
this.a=a;
 }
public void run() 
{
a.m1();
 }
}
class Test
 {
public static void main(String[] args)
 {
A a=new A();
 MyThread1 mt1=new MyThread1(a); 
MyThread2 mt2=new MyThread2(a); 
MyThread3 mt3=new MyThread3(a);
 mt1.setName("AAA"); 
mt2.setName("BBB"); 
mt3.setName("CCC"); 
mt1.start(); 
mt2.start(); 
mt3.start();
 }
}
Inter thread Communication:
The process of providing communication between more than one thread is called as "Inter Thread Communication".
To perform Inter Thread Communication we have to use the following methods.
1.wait()
2.notify()
3.notifyAll()
  • Where wait() method can be used to keep a thread in waiting state.
  • Where notify() method can be used to give a notification to a thread which is available in waiting state.
  • Where notifyAll() method can be used to give a notification to all the threads which are available in waiting state.
The above methods are provided by JAVA in java.lang.Object class. If we want to use these methods in java applications then we must provide "Synchronization".
IN general, Inter Thread Communication will provide solutions for the problems like "Producer Consumer" problems.
In Producer-Consumer problem, producer and cosumer are two threads, where producer has to
produce an item and consumer has to consume that item, the same sequence has to be provided infinite no of times, where Producer must not produce an item with out consuming previous item by consumer and consumer must not consume an item with out producing that item by producer.
class A
 {
boolean flag=true; 
int count=0;
 public synchronized void produce()
 {
try{while(true)
 {
if(flag == true)
 {
count=count+1;
 System.out.println("Producer Produced Item"+count);
 flag=false;
 notify(); 
wait(); 
}
else
 {
wait(); 
}
}
}
catch (Exception e) {e.printStackTrace();
 }
}
public synchronized void consume()
{
try{
while(true)
 {
if(flag == true) 
{
wait();
 }
else 
{
System.out.println("Consumer Consumed Item"+count);
 flag=true; notify();
 wait(); 
}
}
}
catch (Exception e) 
{
e.printStackTrace(); 
}
}
}
class Producer extends Thread
 {
A a; Producer(A a)
 {
this.a=a;
 }
public void run() 
{
a.produce(); 
}
}
class Consumer extends Thread 
{
A a; Consumer(A a)
 {
this.a=a; 
}
public void run()
 {
a.consume();
 }
}
class Test {
public static void main(String[] args)
 {
A a=new A(); 
Producer p=new Producer(a);
 Consumer c=new Consumer(a);
 p.start();
 c.start();
 }
}
Dead Lock:
Dead Lock is a situation , where more than one thread is depending on each other in circular dependency. In java applications, once we are getting deadlock then program will struct in the middle, so that, it will not have any recovery mechanisms, it will have only prevention mechanisms.
class Register_Course extends Thread 
{
Object course_Name; 
Object faculty_Name; 
Register_Course(Object course_Name, Object faculty_Name) 
{
this.course_Name=course_Name;
 this.faculty_Name=faculty_Name; 
}
public void run() 
{
synchronized(course_Name) 
{
System.out.println("Register_Course Thread holds course_Name resource and waiting for faculty_Name resource....."); 
synchronized(faculty_Name) 
{
System.out.println("Register_Course is success, because, Register_Course thread holds both course_Name and faculty_Name resources"); 
}
}
}
}
class Cancel_Course extends Thread {
Object course_Name; 
Object faculty_Name; 
Cancel_Course(Object course_Name, Object faculty_Name) {

this.course_Name=course_Name;
 this.faculty_Name=faculty_Name;
 }
public void run() 
{
synchronized(faculty_Name) 
{
System.out.println("Cancel_Course Thread holds faculty_Name resource and waiting for course_Name resource.....");
 synchronized(course_Name) 
{
System.out.println("Cancel_Course is success, because, Cancel_Course thread holds both faculty_Name and course_Name resources");
 }
}
}
}class Test {public static void main(String[] args) 
{
Object course_Name=new Object(); 
Object faculty_Name=new Object(); 
Register_Course rc=new Register_Course(course_Name, faculty_Name);
 Cancel_Course cc=new Cancel_Course(course_Name, faculty_Name); 
rc.start();
 cc.start();
 }
}

Posted on by