Click here to Skip to main content
15,039,319 members
Articles / Programming Languages / Java
Article
Posted 17 Jun 2021

Tagged as

Stats

1.8K views

Threading in Java : Object Locks V

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
17 Jun 2021CPOL2 min read
Can a thread acquire multiple locks at the same time ?
This is in continuance with my previous article on "Threading in Java: Object Locks - IV". Can a thread acquire multiple locks at the same time ? is the question we will answer in today's article.

Introduction

Can a thread acquire multiple locks at the same time ? . And the answer to this question is Yes! A thread in Java can handle multiple locks. Take the following program.

locks.java
-----------
class processor implements Runnable{
    Object objLock;
	String name;
    public processor(String name, Object objLock){
        this.objLock = objLock;
        this.name = name;
    }
    public void run() {
        display(); 
    }
    public void display() {
	    synchronized(this){
          synchronized(objLock) {
            for (int i = 0 ; i<= 5; i++) {
                System.out.println("i = " + i + " In thread" + Thread.currentThread() + "acquired lock on this i.e. " + name + " and objLock");
            }
          }
		}   
    }
} 

class locks {
    public static void main(String[] args) {
	    Object objLock = new Object();
        processor p1 = new processor("p1",objLock);
		processor p2 = new processor("p2",objLock);
		Thread t1 = new Thread(p1, "t1");
        Thread t2 = new Thread(p1, "t2");
        Thread t3 = new Thread(p2, "t3");
        Thread t4 = new Thread(p2, "t4");

        t1.start();
        t2.start();
		t3.start();
		t4.start();
    }
}


Output:
-------
i = 0 In threadThread[t1,5,main]acquired lock on this i.e. p1 and objLock
i = 1 In threadThread[t1,5,main]acquired lock on this i.e. p1 and objLock
i = 2 In threadThread[t1,5,main]acquired lock on this i.e. p1 and objLock
i = 3 In threadThread[t1,5,main]acquired lock on this i.e. p1 and objLock
i = 4 In threadThread[t1,5,main]acquired lock on this i.e. p1 and objLock
i = 5 In threadThread[t1,5,main]acquired lock on this i.e. p1 and objLock
i = 0 In threadThread[t3,5,main]acquired lock on this i.e. p2 and objLock
i = 1 In threadThread[t3,5,main]acquired lock on this i.e. p2 and objLock
i = 2 In threadThread[t3,5,main]acquired lock on this i.e. p2 and objLock
i = 3 In threadThread[t3,5,main]acquired lock on this i.e. p2 and objLock
i = 4 In threadThread[t3,5,main]acquired lock on this i.e. p2 and objLock
i = 5 In threadThread[t3,5,main]acquired lock on this i.e. p2 and objLock
i = 0 In threadThread[t2,5,main]acquired lock on this i.e. p1 and objLock
i = 1 In threadThread[t2,5,main]acquired lock on this i.e. p1 and objLock
i = 2 In threadThread[t2,5,main]acquired lock on this i.e. p1 and objLock
i = 3 In threadThread[t2,5,main]acquired lock on this i.e. p1 and objLock
i = 4 In threadThread[t2,5,main]acquired lock on this i.e. p1 and objLock
i = 5 In threadThread[t2,5,main]acquired lock on this i.e. p1 and objLock
i = 0 In threadThread[t4,5,main]acquired lock on this i.e. p2 and objLock
i = 1 In threadThread[t4,5,main]acquired lock on this i.e. p2 and objLock
i = 2 In threadThread[t4,5,main]acquired lock on this i.e. p2 and objLock
i = 3 In threadThread[t4,5,main]acquired lock on this i.e. p2 and objLock
i = 4 In threadThread[t4,5,main]acquired lock on this i.e. p2 and objLock
i = 5 In threadThread[t4,5,main]acquired lock on this i.e. p2 and objLock
 

The above program compiles and runs successfully to give us the desired expected output. If you observe the output carefully, you will realize that each and every thread we created in the program was able to acquire a lock on "this" object i.e p1 or p2 as well as the objLock at the same time depending on the context.

Inside main(), threads t1 and t2 are created out of processor object p1 to which the name p1 and the objLock created out of Object class is passed to its constructor. Next, threads t3 and t4 are created out of processor object p2 to which the name p2 and the objLock created out of Object class is passed to its constructor. Thus objLock can be seen by all the Threads. The Thread representing function within run() which is the display() function has the for loop synchronized within "this" and "objLock". Thus any thread has to aquire a lock on itself as well as the lock objLock which is seen by every thread.

When all the threads are started, t1 and t2 race for acquiring a lock on p1 while t3 and t4 race for acquiring a lock on p2 since they are created from p1 and p2 respectively. Lets say t1 acquires a lock on p1 and t3 acquires a lock on p2, then both t1 and t3 compete for objLock. Lets say t1 acquires a lock on objLock and wins the race. Now, t1 will execute the for loop while it is owning both the locks at the same time. Once done, t1 will release both te locks and t3 gets a chance to execute the for loop. Now a similar race condition happens between t2 and t4 and we get a clear in order output.

 

Points of Interest

Hope this example make it clear that a thread can acquire and own multiple locks. Is it a good practice or not ? we will discuss it later.

History

Initial Revision : 18th June 2021

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Chetan Kudalkar
Software Developer (Senior)
India India
I am a Software engineer with around 7+ years of experience. Most of my experience is in Storage technology.

Comments and Discussions

 
SuggestionPut parts together Pin
Klaus Luedenscheidt17-Jun-21 17:49
MemberKlaus Luedenscheidt17-Jun-21 17:49 
GeneralRe: Put parts together Pin
Chetan Kudalkar19-Jun-21 0:04
MemberChetan Kudalkar19-Jun-21 0:04 
GeneralRe: Put parts together Pin
Klaus Luedenscheidt19-Jun-21 17:50
MemberKlaus Luedenscheidt19-Jun-21 17:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.