Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Hello I just had phone interview I was not able to answer this question and would like to know the answer, I believe, its advisable to reach out for answers that you don't know. Please encourage me to understand the concept. His question was: "The synchronized block only allows one thread a time into the mutual exclusive section. When a thread exits the synchronized block, the synchronized ...
I'm reading the source of java.util.concurrent.ArrayBlockingQueue, and found some code I don't understand: private final ReentrantLock lock; public boolean offer(E e) { if (e == null) throw new NullPointerException(); final ReentrantLock lock = this.lock; lock.lock(); try { if (count == items.length) return false; else { insert(e); ...
(Please leave a comment if the point is not clear) I'm studying the book "Distributed Systems" (by Tanenbaum & Van Steen) and they say something that seems to conflict to what seems to be instead thought by many on Java RMI and synchronized methods. What I thought is that using a synchronized method on a Remote Object implementation (so the real implementation running at the server) concu...
What happens when you concurrently open two (or more) FileOutputStreams on the same file? The Java API says this: Some platforms, in particular, allow a file to be opened for writing by only one FileOutputStream (or other file-writing object) at a time. I'm guessing Windows isn't such a platform, because I have two threads that read some big file (each one a different one) then write it ...
If I want to ensure exclusive access to an object in Java, I can write something like this: ... Zoo zoo = findZoo(); synchronized(zoo) { zoo.feedAllTheAnimals(); ... } Is there a way to check if an object is currently locked? I don't want my thread to wait if another thread is accessing zoo. If zoo is not locked, I want my thread to acquire the lock and execute the synchronized bloc...
The Semaphore class overview in developer.android.com looks pretty good - for those who are already familiar with the concepts and terminology. I am familiar with some of the acronyms and other jargon there (e.g. FIFO, lock, etc.) but others such as permits, fairness and barging are new to me. Can you recommend a good online source for explaining these concepts? (I can probably figure out wha...
I have a process A that contains a table in memory with a set of records (recordA, recordB, etc...) Now, this process can launch many threads that affect the records, and sometimes we can have 2 threads trying to access the same record - this situation must be denied. Specifically if a record is LOCKED by one thread I want the other thread to abort (I do not want to BLOCK or WAIT). Currently ...
If I have a synchronized method and two threads are waiting to enter it they seem to enter the thread Last In First Executed. Is there a way to make this First In First Executed? This is the unit test that I'm using: package com.test.thread; import org.apache.log4j.Logger; import org.junit.Test; public class ThreadTest { private static final Logger log = Logger.getLogger(ThreadTest.cla...
I have two threads that want to synchonize on the same object. Thead A needs to be able to interrupt Thread B if a certain condition has been fullfilled. Here is some pseudo-code of what the two threads do/should do. A: public void run() { while(true) { //Do stuff synchronized(shared) { //Do more stuff if(condition) { ...
If a thread holds a lock , what happens when the thread needs to enter another critical section controlled by the same lock?
If I have the following code class SomeClass { ... public synchronized methodA() { .... } public synchronized methodB(){ .... } } This would synchronized on the 'this' object. However, if my main objective here is to make sure multiple threads don't use methodA (or methodB) at the same time, but they CAN use methodA AND methodB concurrently, then is this kind of design restrictive? sinc...
I commented earlier on this question ("Why java.lang.Object is not abstract?") stating that I'd heard that using a byte[0] as a lock was slightly more efficient than using an java.lang.Object. I'm sure I've read this somewhere but I can't recall where: Does anyone know if this is actually true? I suspect it's due to the instantiation of byte[0] requiring slightly less byte code than Object, a...
I’m debugging a Java application that runs several threads. After a while of watching the log it seems that one of those threads is not running anymore. My guess is that the thread is waiting for a lock that is never released (the last output is before calling a synchronized method). Can I configure a timeout to the thread; a sort of “wait for this lock but if it not available after 10 second...
I have a class that contains an object of type Object (which is used as a monitor for synchronization). Since Objects are not Serializable, what can I substitute to make serialization work?
We have three web services (/a, /b, /c) where each service maps to a method (go()) in a separate Java class (ClassA, ClassB, ClassC). Only one service should run at the same time (ie: /b cannot run while /a is running). However as this is a REST API there is nothing to prevent clients from requesting the services run concurrently. What is the best and most simple method on the server to en...
Let's say I have 2 threads, t1 and t2, and a lock object, m. Thread t1 is in an infinite loop, where at each iteration, it grabs a lock on m, does some work, unlocks m and starts over immediately. During one iteration, t2 requests a lock on m but gets blocked by t1 and has to wait. Now, when t1 unlocks m, is it guaranteed that t2 will obtain the next lock on m? or can t1 sneak ahead of it at th...
My colleague and I have a web application that uses Spring 3.0.0 and JPA (hibernate 3.5.0-Beta2) on Tomcat inside MyEclipse. One of the data structures is a tree. Just for fun, we tried stress-testing the "insert node" operation with JMeter, and found a concurrency problem. Hibernate reports finding two entities with the same private key, just after a warning like this: WARN [org.hibernate.e...
As far as I know, wait() and notify() have been replaced with better concurrency mechanisms. So, what better alternative would you choose, say for implementing a synchronized queue? In what sense exactly are they "better"? Edit: This ("implement a synchronous queue") is an interview question. An acceptable answer cannot use BlockingQueue or other queue implementation. It might, however, use o...
Suppose I have an ExecutorService (which can be a thread pool, so there's concurrency involved) which executes a task at various times, either periodically or in response to some other condition. The task to be executed is the following: if this task is already in progress, do nothing (and let the previously-running task finish). if this task is not already in progress, run Algorithm X, which...
Suppose we have some resource(a file on disk) in which we have to write bytes produced by different threads. These threads are spawned by some process that listens to some events and spawns a thread every time when event occures. As we have only one resource, we have to synchronize methods of the class which performs write operation: synchronized void write(byte [] bytes) { //write ...
we have two threads accessing one list via a synchronized method. Can we a) rely on the run time to make sure that each of them will receive access to the method based on the order they tried to or b) does the VM follow any other rules c) is there a better way to serialize the requests? Many thanks!
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Sun designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Sun in the LICENSE file that accompanied this code.
   *
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * version 2 for more details (a copy is included in the LICENSE file that
  * accompanied this code).
  *
  * You should have received a copy of the GNU General Public License version
  * 2 along with this work; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
  */
 
 /*
  * This file is available under and governed by the GNU General Public
  * License version 2 only, as published by the Free Software Foundation.
  * However, the following notice accompanied the original version of this
  * file:
  *
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
  */
 
 package java.util.concurrent.locks;
 import java.util.*;
A reentrant mutual exclusion Lock with the same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements, but with extended capabilities.

A ReentrantLock is owned by the thread last successfully locking, but not yet unlocking it. A thread invoking lock will return, successfully acquiring the lock, when the lock is not owned by another thread. The method will return immediately if the current thread already owns the lock. This can be checked using methods isHeldByCurrentThread(), and getHoldCount().

The constructor for this class accepts an optional fairness parameter. When set true, under contention, locks favor granting access to the longest-waiting thread. Otherwise this lock does not guarantee any particular access order. Programs using fair locks accessed by many threads may display lower overall throughput (i.e., are slower; often much slower) than those using the default setting, but have smaller variances in times to obtain locks and guarantee lack of starvation. Note however, that fairness of locks does not guarantee fairness of thread scheduling. Thus, one of many threads using a fair lock may obtain it multiple times in succession while other active threads are not progressing and not currently holding the lock. Also note that the untimed tryLock method does not honor the fairness setting. It will succeed if the lock is available even if other threads are waiting.

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

In addition to implementing the Lock interface, this class defines methods isLocked and getLockQueueLength, as well as some associated protected access methods that may be useful for instrumentation and monitoring.

Serialization of this class behaves in the same way as built-in locks: a deserialized lock is in the unlocked state, regardless of its state when serialized.

This lock supports a maximum of 2147483647 recursive locks by the same thread. Attempts to exceed this limit result in java.lang.Error throws from locking methods.

Author(s):
Doug Lea
Since:
1.5
public class ReentrantLock implements Lockjava.io.Serializable {
    private static final long serialVersionUID = 7373984872572414699L;
    
Synchronizer providing all implementation mechanics
    private final Sync sync;

    
Base of synchronization control for this lock. Subclassed into fair and nonfair versions below. Uses AQS state to represent the number of holds on the lock.
    static abstract class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;

        
Performs Lock.lock(). The main reason for subclassing is to allow fast path for nonfair version.
        abstract void lock();

        
Performs non-fair tryLock. tryAcquire is implemented in subclasses, but both need nonfair try for trylock method.
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }
        protected final boolean isHeldExclusively() {
            // While we must in general read state before owner,
            // we don't need to do so to check if current thread is owner
            return getExclusiveOwnerThread() == Thread.currentThread();
        }
        final ConditionObject newCondition() {
            return new ConditionObject();
        }
        // Methods relayed from outer class
        final Thread getOwner() {
            return getState() == 0 ? null : getExclusiveOwnerThread();
        }
        final int getHoldCount() {
            return isHeldExclusively() ? getState() : 0;
        }
        final boolean isLocked() {
            return getState() != 0;
        }

        
Reconstitutes this lock instance from a stream.

Parameters:
s the stream
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOExceptionClassNotFoundException {
            s.defaultReadObject();
            setState(0); // reset to unlocked state
        }
    }

    
Sync object for non-fair locks
    final static class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        
Performs lock. Try immediate barge, backing up to normal acquire on failure.
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }
        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }

    
Sync object for fair locks
    final static class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;
        final void lock() {
            acquire(1);
        }

        
Fair version of tryAcquire. Don't grant access unless recursive call or no waiters or is first.
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }

    
Creates an instance of ReentrantLock. This is equivalent to using ReentrantLock(false).
    public ReentrantLock() {
         = new NonfairSync();
    }

    
Creates an instance of ReentrantLock with the given fairness policy.

Parameters:
fair true if this lock should use a fair ordering policy
    public ReentrantLock(boolean fair) {
         = (fair)? new FairSync() : new NonfairSync();
    }

    
Acquires the lock.

Acquires the lock if it is not held by another thread and returns immediately, setting the lock hold count to one.

If the current thread already holds the lock then the hold count is incremented by one and the method returns immediately.

If the lock is held by another thread then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired, at which time the lock hold count is set to one.

    public void lock() {
        .lock();
    }

    
Acquires the lock unless the current thread is interrupted.

Acquires the lock if it is not held by another thread and returns immediately, setting the lock hold count to one.

If the current thread already holds this lock then the hold count is incremented by one and the method returns immediately.

If the lock is held by another thread then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of two things happens:

  • The lock is acquired by the current thread; or
  • Some other thread interrupts the current thread.

If the lock is acquired by the current thread then the lock hold count is set to one.

If the current thread:

  • has its interrupted status set on entry to this method; or
  • is interrupted while acquiring the lock,
then java.lang.InterruptedException is thrown and the current thread's interrupted status is cleared.

In this implementation, as this method is an explicit interruption point, preference is given to responding to the interrupt over normal or reentrant acquisition of the lock.

Throws:
java.lang.InterruptedException if the current thread is interrupted
    public void lockInterruptibly() throws InterruptedException {
        .acquireInterruptibly(1);
    }

    
Acquires the lock only if it is not held by another thread at the time of invocation.

Acquires the lock if it is not held by another thread and returns immediately with the value true, setting the lock hold count to one. Even when this lock has been set to use a fair ordering policy, a call to tryLock() will immediately acquire the lock if it is available, whether or not other threads are currently waiting for the lock. This "barging" behavior can be useful in certain circumstances, even though it breaks fairness. If you want to honor the fairness setting for this lock, then use tryLock(0, TimeUnit.SECONDS) which is almost equivalent (it also detects interruption).

If the current thread already holds this lock then the hold count is incremented by one and the method returns true.

If the lock is held by another thread then this method will return immediately with the value false.

Returns:
true if the lock was free and was acquired by the current thread, or the lock was already held by the current thread; and false otherwise
    public boolean tryLock() {
        return .nonfairTryAcquire(1);
    }

    
Acquires the lock if it is not held by another thread within the given waiting time and the current thread has not been interrupted.

Acquires the lock if it is not held by another thread and returns immediately with the value true, setting the lock hold count to one. If this lock has been set to use a fair ordering policy then an available lock will not be acquired if any other threads are waiting for the lock. This is in contrast to the tryLock() method. If you want a timed tryLock that does permit barging on a fair lock then combine the timed and un-timed forms together:

if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
 

If the current thread already holds this lock then the hold count is incremented by one and the method returns true.

If the lock is held by another thread then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens:

  • The lock is acquired by the current thread; or
  • Some other thread interrupts the current thread; or
  • The specified waiting time elapses

If the lock is acquired then the value true is returned and the lock hold count is set to one.

If the current thread:

  • has its interrupted status set on entry to this method; or
  • is interrupted while acquiring the lock,
then java.lang.InterruptedException is thrown and the current thread's interrupted status is cleared.

If the specified waiting time elapses then the value false is returned. If the time is less than or equal to zero, the method will not wait at all.

In this implementation, as this method is an explicit interruption point, preference is given to responding to the interrupt over normal or reentrant acquisition of the lock, and over reporting the elapse of the waiting time.

Parameters:
timeout the time to wait for the lock
unit the time unit of the timeout argument
Returns:
true if the lock was free and was acquired by the current thread, or the lock was already held by the current thread; and false if the waiting time elapsed before the lock could be acquired
Throws:
java.lang.InterruptedException if the current thread is interrupted
java.lang.NullPointerException if the time unit is null
    public boolean tryLock(long timeoutTimeUnit unitthrows InterruptedException {
        return .tryAcquireNanos(1, unit.toNanos(timeout));
    }

    
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 java.lang.IllegalMonitorStateException is thrown.

Throws:
java.lang.IllegalMonitorStateException if the current thread does not hold this lock
    public void unlock() {
        .release(1);
    }

    
Returns a Condition instance for use with this Lock instance.

The returned Condition instance supports the same usages as do the java.lang.Object monitor methods (java.lang.Object.wait(), notify, and java.lang.Object.notifyAll()) when used with the built-in monitor lock.

  • If this lock is not held when any of the Condition waiting or Condition.signal() methods are called, then an java.lang.IllegalMonitorStateException is thrown.
  • When the condition waiting methods are called the lock is released and, before they return, the lock is reacquired and the lock hold count restored to what it was when the method was called.
  • If a thread is interrupted while waiting then the wait will terminate, an java.lang.InterruptedException will be thrown, and the thread's interrupted status will be cleared.
  • Waiting threads are signalled in FIFO order.
  • The ordering of lock reacquisition for threads returning from waiting methods is the same as for threads initially acquiring the lock, which is in the default case not specified, but for fair locks favors those threads that have been waiting the longest.

Returns:
the Condition object
    public Condition newCondition() {
        return .newCondition();
    }

    
Queries the number of holds on this lock by the current thread.

A thread has a hold on a lock for each lock action that is not matched by an unlock action.

The hold count information is typically only used for testing and debugging purposes. For example, if a certain section of code should not be entered with the lock already held then we can assert that fact:

 class X {
   ReentrantLock lock = new ReentrantLock();
   // ...
   public void m() {
     assert lock.getHoldCount() == 0;
     lock.lock();
     try {
       // ... method body
     } finally {
       lock.unlock();
     }
   }
 }
 

Returns:
the number of holds on this lock by the current thread, or zero if this lock is not held by the current thread
    public int getHoldCount() {
        return .getHoldCount();
    }

    
Queries if this lock is held by the current thread.

Analogous to the java.lang.Thread.holdsLock(java.lang.Object) method for built-in monitor locks, this method is typically used for debugging and testing. For example, a method that should only be called while a lock is held can assert that this is the case:

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

   public void m() {
       assert lock.isHeldByCurrentThread();
       // ... method body
   }
 }
 

It can also be used to ensure that a reentrant lock is used in a non-reentrant manner, for example:

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

   public void m() {
       assert !lock.isHeldByCurrentThread();
       lock.lock();
       try {
           // ... method body
       } finally {
           lock.unlock();
       }
   }
 }
 

Returns:
true if current thread holds this lock and false otherwise
    public boolean isHeldByCurrentThread() {
        return .isHeldExclusively();
    }

    
Queries if this lock is held by any thread. This method is designed for use in monitoring of the system state, not for synchronization control.

Returns:
true if any thread holds this lock and false otherwise
    public boolean isLocked() {
        return .isLocked();
    }

    
Returns true if this lock has fairness set true.

Returns:
true if this lock has fairness set true
    public final boolean isFair() {
        return  instanceof FairSync;
    }

    
Returns the thread that currently owns this lock, or null if not owned. When this method is called by a thread that is not the owner, the return value reflects a best-effort approximation of current lock status. For example, the owner may be momentarily null even if there are threads trying to acquire the lock but have not yet done so. This method is designed to facilitate construction of subclasses that provide more extensive lock monitoring facilities.

Returns:
the owner, or null if not owned
    protected Thread getOwner() {
        return .getOwner();
    }

    
Queries whether any threads are waiting to acquire this lock. Note that because cancellations may occur at any time, a true return does not guarantee that any other thread will ever acquire this lock. This method is designed primarily for use in monitoring of the system state.

Returns:
true if there may be other threads waiting to acquire the lock
    public final boolean hasQueuedThreads() {
        return .hasQueuedThreads();
    }


    
Queries whether the given thread is waiting to acquire this lock. Note that because cancellations may occur at any time, a true return does not guarantee that this thread will ever acquire this lock. This method is designed primarily for use in monitoring of the system state.

Parameters:
thread the thread
Returns:
true if the given thread is queued waiting for this lock
Throws:
java.lang.NullPointerException if the thread is null
    public final boolean hasQueuedThread(Thread thread) {
        return .isQueued(thread);
    }


    
Returns an estimate of the number of threads waiting to acquire this lock. The value is only an estimate because the number of threads may change dynamically while this method traverses internal data structures. This method is designed for use in monitoring of the system state, not for synchronization control.

Returns:
the estimated number of threads waiting for this lock
    public final int getQueueLength() {
        return .getQueueLength();
    }

    
Returns a collection containing threads that may be waiting to acquire this lock. Because the actual set of threads may change dynamically while constructing this result, the returned collection is only a best-effort estimate. The elements of the returned collection are in no particular order. This method is designed to facilitate construction of subclasses that provide more extensive monitoring facilities.

Returns:
the collection of threads
    protected Collection<ThreadgetQueuedThreads() {
        return .getQueuedThreads();
    }

    
Queries whether any threads are waiting on the given condition associated with this lock. Note that because timeouts and interrupts may occur at any time, a true return does not guarantee that a future signal will awaken any threads. This method is designed primarily for use in monitoring of the system state.

Parameters:
condition the condition
Returns:
true if there are any waiting threads
Throws:
java.lang.IllegalMonitorStateException if this lock is not held
java.lang.IllegalArgumentException if the given condition is not associated with this lock
java.lang.NullPointerException if the condition is null
    public boolean hasWaiters(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return .hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
    }

    
Returns an estimate of the number of threads waiting on the given condition associated with this lock. Note that because timeouts and interrupts may occur at any time, the estimate serves only as an upper bound on the actual number of waiters. This method is designed for use in monitoring of the system state, not for synchronization control.

Parameters:
condition the condition
Returns:
the estimated number of waiting threads
Throws:
java.lang.IllegalMonitorStateException if this lock is not held
java.lang.IllegalArgumentException if the given condition is not associated with this lock
java.lang.NullPointerException if the condition is null
    public int getWaitQueueLength(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
    }

    
Returns a collection containing those threads that may be waiting on the given condition associated with this lock. Because the actual set of threads may change dynamically while constructing this result, the returned collection is only a best-effort estimate. The elements of the returned collection are in no particular order. This method is designed to facilitate construction of subclasses that provide more extensive condition monitoring facilities.

Parameters:
condition the condition
Returns:
the collection of threads
Throws:
java.lang.IllegalMonitorStateException if this lock is not held
java.lang.IllegalArgumentException if the given condition is not associated with this lock
java.lang.NullPointerException if the condition is null
    protected Collection<ThreadgetWaitingThreads(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
    }

    
Returns a string identifying this lock, as well as its lock state. The state, in brackets, includes either the String "Unlocked" or the String "Locked by" followed by the name of the owning thread.

Returns:
a string identifying this lock, as well as its lock state
    public String toString() {
        Thread o = .getOwner();
        return super.toString() + ((o == null) ?
                                   "[Unlocked]" :
                                   "[Locked by thread " + o.getName() + "]");
    }
New to GrepCode? Check out our FAQ X