Solved

Being able to pass a lock between threads?

Posted on 2014-11-19
4
263 Views
Last Modified: 2014-11-24
MCCarl:  This one's for you!  

You suggested the "reentrant lock" in another thread, and I've been looking at it, and it looks like it MIGHT be just what I need.  Here was the code I'd written:  

//Theoretically, this should allow objects to be synchronized across methods and threads instead of just within a single method.
//In practice, this will probably just cause a ton of race conditions and problems.
public class Synchronizer {

	//Track the synchronization of the object manually.
	boolean booLocked = false;
	
	//This is my attempt at a public locking mechanism that will (theoretically) allow thread safety across methods.
	//So if they want to turn the lock "on" first, do the system sync.
	public synchronized void lock() {

		//Now, if the thread is this far, but the boolean shows that the sync is already "on" have the thread wait until it's available.
		while (booLocked) {
			//Allow other threads to run if needed.
			Thread.yield();
		}
		//Theoretically, if we're this far, only one thread should have been permitted to get through the system's "synchronized" function.  So flipping the "locked"
		//to "true" then stepping out of the sync should allow any competing threads to get through one at a time and wait for the boolean to be flipped to "false" again.
		booLocked = true;
 
	}
	
	public void unLock() {
		//Simply flip the switch to unlock.
		booLocked = false;
	}
	
}

Open in new window


The idea would be for me to be able to have an object that can be passed between threads, so that a "lock" on an object would no longer be limited to the method that "synchronized" was called in.  I wrote this code to give me an object that I could pass around like a baton, and only after the CORRECT object called "unlock" could anything be done.  This object that unlocks it, though, might not be in the same thread as the one that locked it.  

Basically, imagine a scenario where I have one thread whose job is to "load and lock" objects, then toss them into a queue.  Other threads will be trying to get at these objects, but will have to wait until they're unlocked.

Another thread picks up any objects in this queue, does some stuff to them, then "unlocks" them, allowing the other threads access to grab and lock them themselves.  

One lock object, used by all threads, but the lock and unlock does not necessarily have to happen within the same thread.  That's the goal behind this code.  

Is this what the ReentrantLock does?  

According to the Oracle docs:  

It is recommended practice to always immediately follow a call to lock with a try block, most typically in a before/after construction such as:

 class X {
   private final ReentrantLock lock = new ReentrantLock();
   // ...

   public void m() {
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }

Open in new window


This seems to indicate that once again, within the same method, the locks and unlocks should be together.  Am I reading this wrong?
0
Comment
Question by:Javin007
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
4 Comments
 
LVL 27

Accepted Solution

by:
dpearson earned 500 total points
ID: 40453129
If the goal is to have Thread A lock an object and Thread B unlock it, then I don't think you can use ReentrantLock because only the locking thread can unlock it:

public void unlock()
Attempts to release this lock.
If the current thread is the holder of this lock then the hold count is decremented. If the hold count is now zero then the lock is released. If the current thread is not the holder of this lock then IllegalMonitorStateException is thrown.

I think instead you maybe want to use a Semaphore
(https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html)

A Semaphore conceptually is more of a set of flags - which you can then use to decide when somebody can do an operation or not.  (You can use a Semaphore to implement the concept of a Lock - they're more primitive than a Lock).  The big difference for you is the "release()" method for a Semaphore is not thread specific:

public void release()
Releases a permit, returning it to the semaphore.
Releases a permit, increasing the number of available permits by one. If any threads are trying to acquire a permit, then one is selected and given the permit that was just released. That thread is (re)enabled for thread scheduling purposes.

There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire(). Correct usage of a semaphore is established by programming convention in the application.

Doug
0
 
LVL 16

Expert Comment

by:krakatoa
ID: 40453266
My name's not mccarl either, but as mentioned before, util.concurrent holds many useful classes, and CyclicBarrier is one you can also read up on.

And "passing a lock" is not only going to be clock-costly, but is not really in the paradigm. Using a thread-superior mechanism that is already in the model is preferable.
0
 
LVL 35

Expert Comment

by:mccarl
ID: 40453998
As Doug has said, it sounds like Semaphore is what you may need, however, I am interested more in your core requirements. You said...

Basically, imagine a scenario where I have one thread whose job is to "load and lock" objects, then toss them into a queue.  Other threads will be trying to get at these objects, but will have to wait until they're unlocked.

Another thread picks up any objects in this queue, does some stuff to them, then "unlocks" them, allowing the other threads access to grab and lock them themselves.  
Now, you may have simplified this a bit just to describe it here, but if this were the actual requirement, could you implement by using 2 queues. The first thread you mention above would load objects onto one queue. Then the last thread that you mention can "...picks up any objects in this queue, does some stuff to them..." BUT then it places them on a 2nd queue. Then these "other threads" can get the objects from the 2nd queue. There is no locking required at all now.

As I said, I'm guessing the actual requirements are more than just this and that may have an impact, so if you can more fully describe what you need, we may be able to provide more assistance.
0
 
LVL 4

Author Closing Comment

by:Javin007
ID: 40462489
Looks like semaphores are the direction I needed to go in. Thanks!
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
Suggested Courses

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question