- 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();
}
}