Throw exception if another thread is still holding the lock? - java

I'm working on a multithreading program for school. It basically just hands off a string from one thread to another. Multiple threads are operating on a single instance of a class. They call methods like pass, receive, etc. The passing thread will block until a receiver comes(or timeout), and a receiver will block until a passer comes... Its a basic exercise in coordinating threads.
One of the tests I'm really struggling with and it's called lock hog. Lets say one of the threads calls receive and the pass is complete, but the thread doesn't let go of the lock. Apparently what's supposed to happen is that the next thread that comes in should throw an illegal state exception, but I can't figure out how this is done. Is there a way to let a thread know that another thread is still holding the lock? Thanks in advance.

Related

When does thread die in ThreadPoolExecutor

Problem:
I wanted to know when a RunTimeException is thrown in run method of thread, will thread local of that thread be preserved? Answer to this question lies in what I'm asking below. So with that said, if thread dies(when exception is thrown) it's thread local snapshot get's cleared up or if thread does not die what happens to thread local in that case. Do we need to programmatically handle that?
Scenario:
During heavy load, request came in and processing took way too long and before response was created, async context times out. What happens in this scenario? What happens to the thread that is processing the request?
Here's more details :
I've been researching on how ThreadPoolExecutors internally work. What I'm curious to know is what happens when a RunTimeException is thrown in run method of thread. Does it get killed and ThreadPoolExecutor ends up creating brand new thread? Or JVM somehow does not let that thread to die, so that it can reused in
the pool. I think the thread dies and so does it's ThreadLocal snapshot.
I wanted to get some insight on exactly how ThreadPoolExecutor handle exceptions and how life cycle of a particular thread revolves around that.
Thanks for your help!
Thanks everyone! I got my answer.
Thread dies when an exception is thrown. Only catch here is if we reference a thread id in thread local that can cause a thread leak if that is not cleared properly.
Thread id can be reused as per java docs. In my case I was putting putting some stuff in thread local referencing to thread id (Thread.currentThread.getId). Best way to clear that up is to override afterExecute(java.lang.Runnable, java.lang.Throwable) and clean up things in there.
From java docs:
public long getId()
Returns the identifier of this Thread. The thread ID is a positive long number generated when this thread was created. The thread ID is unique and remains unchanged during its lifetime. When a thread is terminated, this thread ID may be reused.

Sychronizing run() method of thread object

Caution: Don't synchronize a thread object's run() method because
situations arise where multiple threads need to execute run(). Because
those threads attempt to synchronize on the same object, only one
thread at a time can execute run(). As a result, each thread must wait
for the previous thread to terminate before it can access run().
From : http://www.javaworld.com/article/2074318/java-concurrency/java-101--understanding-java-threads--part-2--thread-synchronization.html?page=2
How can different threads execute, run() of same Thread object?
Some general advice about when it comes to synchronizing that seems relevant here: don't put synchronization in your threads or runnables, put it in the data structures that the threads are accessing. If you guard the data structure with locks then you are assured that no threads can access it in an unsafe way, because the data structure is enforcing safe access. If you leave synchronization up to the threads then someone can write a new thread that doesn't do the appropriate locking and possibly corrupt the data structures being accessed. Remember the point of synchronization is to protect data from unsafe concurrent modification.
(If you look at the JavaWorld article, listings 2 and 3 illustrate this; listing 3 is noticeably saner than listing 2 in that the FinTrans data is protecting its own integrity where listing 2 the threads are doing the synchronizing. The author argues for listing 3 as having better granularity for locking, and doesn't address the point about having data structures protect their own integrity. Maybe that's because he's whipping out toy examples and isn't taking any of them so seriously; after all, at the top of the page he's showing using a string as a lock, which is a pretty bad idea.)
Also the Java API documentation discourages you from
locking on thread objects. The Java threading implementation locks on threads, for instance when joining a thread, so any manipulations you do may get tangled up with what the Java threading API does; for instance, if you try to lock on threads any notify calls you make may get consumed by other threads trying to join. Also you may see some strange things, for instance when a thread terminates it sends a notification to anything waiting on its monitor. If you make the run method of a Thread subclass synchronized then the running thread has to acquire its own lock. If another thread wants to join on it then (unless the subclassed Thread gives up the lock by waiting) that makes it impossible for any thread to join (since that involves waiting, which requires acquiring the lock on the Thread object), so instead of the joining thread briefly acquiring the lock and settling down to wait, the joining thread is likely to be hanging out in the waitset contending for the lock until the to-be-joined-on thread terminates.
Another point is it's better to implement your tasks as Runnables rather than as Thread objects. I cannot think of a situation where it would be preferable to implement the run method of a Thread object than to implement Runnable, unless I was trying to create a confusing situation on purpose, or was typing a fast-and-dirty demo. (I really wonder whether the reason for Thread implementing Runnable could be to make it more convenient for people to write fast-n-dirty demo code.) Making your task a Runnable makes it clear that you have some logic that isn't tied down to being run as a new thread but alternatively can be handed off to an executor which can be in charge of how that task is executed. (You can do this with a Thread object, but it's confusing.) So another reason not to be making a synchronized run method on Thread objects is because you shouldn't be subclassing Thread in order to override the run method (and in general it's usually preferable to use executors with Runnables over spinning up your own threads).

Thread behaviour

From a Thread perspective, what is a block, wait and lock? Rather,is it necessary to have all these three in any operation? For example, in a producer-consumer pattern how this things are implemented.
Thanks in advance
A blocking operation is one that blocks the thread until the operation completes. Blocking a thread is the process of telling the thread scheduler (usually the operating system, although there are user-level thread libraries) not to run a thread until that thread is woken up. There are many kinds of blocking operations, and one example is file I/O. As with any other blocking operation, the method doesn't return until the relevant operation (in this case, file I/O) has completed.
A wait is a particular kind of blocking operation used for thread synchronization. Specifically, it says "please block the thread that called wait until some other thread wakes it up." In Java, wait is a method. The corresponding wake-up method is notify.
A lock is a higher-level abstraction that says "only allow a limited number of threads into this region of code." Most commonly, that limited number is 1, in which case a mutex (which I explain in plenty of detail in this SO answer) is the preferred locking primitive in a lower-level language like C. In Java, the most common locking primitive is called a monitor. There is a notion of owning an object's monitor (every object has a monitor), and waiting on a monitor, and waking up a thread that is waiting on a monitor. How do we accomplish this? You guessed it - we use the wait method to wait on a monitor, and notify to wake up one of the threads that is waiting on the monitor.
Now an answer that will probably sound a bit like Greek, given that you are just starting with concurrency: To implement the producer-consumer pattern, the most common strategy is to use two semaphores (plus a mutex to synchronize access to the buffer). A semaphore is usually implemented with a mutex, but is a higher-order construct because it allows counting some resource. So you keep one semaphore to count the number of items in the buffer, and one to count the number of empty spaces in the buffer. The producer waits on the empty space semaphore and adds items to the buffer whenever space becomes available, and the consumer waits on the items semaphore and consumes an item whenever an item becomes available.
Now I've defined what these things are, but I haven't really talked about how to use them. That, however, is worth several lectures in a college course, and is certainly too much for a StackOverflow answer. I'd recommend the concurrency lessons in the Java tutorials as a way to get started with threading. Also, look up college courses on the web. Many schools post notes publicly online, so with a little searching you can often find high-quality material.
EDIT: A description of the difference between wait and blocking I/O
Before you begin reading this, make sure you're familiar with what a thread is, and what a process is. I give an explanation in the first four paragraphs of this SO answer, and Wikipedia has a more detailed explanation (albeit with less historical context).
Each thread has one very important piece of information: an instruction pointer (there are other important pieces of information associated with each thread, but they aren't important now). The instruction pointer is a JVM-maintained pointer to the currently executing bytecode instruction. Every time you execute an instruction (each instruction is an abstract representation of a very simple operation, such as "call method foo on object x), the instruction pointer is moved forward to some "next instruction." To run your program, the JVM sets the instruction pointer to the beginning of main and keeps executing instructions and moving the instruction pointer forward until the program exits somehow.
A blocking operation stops the instruction pointer from moving forward until some event occurs to cause the instruction pointer to move forward again. Certainly the thread that initiated the blocking operation can't make this event happen, because that thread's instruction pointer isn't moving forward i.e. that thread is doing nothing.
Now, there are a lot of different kinds of blocking operations. One is blocking I/O. If you call System.out.println, for example, the println method doesn't return until the text is written out to the console. In this case, the instruction pointer stops somewhere inside System.out.println, and the operating system signals the thread to wake up whenever the console printing finishes. So the thread doesn't have to start its own instruction pointer moving again, but the method still returns just after the text is written to the console. So, at a very high level:
Thread 0 calls System.out.println("foo")
Thread 0's instruction pointer stops moving while the operating system writes "foo" to the console
When the operating system is done writing to the console, it notifies the JVM, and the JVM automatically starts moving thread 0's instruction pointer moving again. All of this happens without the programmer who writes System.out.println having to think about it.
Another completely separate kind of blocking operation is encapsulated in the Object.wait method. Whenever a thread calls Object.wait, that thread's instruction pointer stops moving, but instead of the operating system starting the movement of the instruction pointer again, another thread does the job. In this case, there is no external event that will cause the thread's instruction pointer to be restarted (as in the blocking I/O case), but there is an event internal to the program. As I said, another thread will start the instruction pointer moving again by calling Object.notify. So, at a very high level:
Thread 0 calls x.wait() on some object
Thread 0's instruction pointer stops moving
Thread 1 calls x.notify() on the same object x
Thread 0's instruction pointer starts moving again
Thread 0 and thread 1 are now executing concurrently
Notice that a lot more work has to go into writing wait/notify code correctly - the JVM and the operating system don't do all the work for you this time. They still actually do most of the work for you, but you actually have to think about calling wait and notify, and how they allow you to communicate between threads, implement locks, and more.
So there are two morals to this story. The first is that blocking I/O and wait are completely different beasts. In both cases, a thread is blocked, but in the blocking I/O case the thread is woken up automatically by the operating system, while in the wait case the thread has to rely on another thread calling notify in order to wake it up. The second is that concurrent programming is harder to reason about than serial programming. The toy examples I've put in this answer don't really do the second point justice.
No, you don't necessarily need a lock or a wait just because you're using threads. However, if you want the threads to exchange data, they are often useful.
Here's a good explanation with an example of the consumer producer model:
http://www.ase.md/~aursu/JavaThreadsSynchronization.html
Cheers!
Block : Prevent the Executing.
Wait : Suspends the current thread.
Lock : When you lock it others can't Use it.
Consider online purchase when a customer buys a Movie Ticket
As soon as he chooses the seat. Others won't be able to get those seat at the same time(Locking those seats).

Making a single thread execute to completion

I was asked this question in an interview - not sure if it makes sense.
You have several threads of same priority started and running, how do you make sure that a particular thread among those is run to completion first?
You can't use wait() and sleep() trick on other threads..
EDIT:
Modifying the other threads is not allowed.
have one thread join() the other
Since you are not allowed to modify the threads, you will have to suspend the waiting threads and join() on the thread that must complete first.
I'll leave the following (I answered before the clarification about modifying the threads was added) for completeness, but under the clarified constraints of the problem these methods would be disallowed:
Have each of the other threads call join() on the thread that should complete first. This will cause them to wait until that thread has terminated, but using considerably less CPU time than a sleep() loop would.
Thread first = new FirstThread();
Thread after1 = new AfterThread(first);
Thread after2 = new AfterThread(first);
In the run method for AfterThread:
first.join();
// Do the rest of this thread's code
You can also pass a timeout to join().
An alternative method might be to create a lock that only a particular named thread can acquire, until after that named thread has acquired and released it once.
It's deprecated and inherently unsafe (so you should never use it), but you could suspend() all the other threads, then join() on the one you want to finish first, then resume().
I'm not sure if that's what they're going for. If it is, I would doubt either their interview skills or their Java knowledge.
The "good" solutions that I can think of require at least trivially modifying the code that the threads are going to run. Are you sure that it is off limits to modify those threads?

Confusing use of synchronized in Java: pattern or anti-pattern?

I'm doing a code review for a change in a Java product I don't own. I'm not a Java expert, but I strongly suspect that this is pointless and indicates a fundamental misunderstanding of how synchronization works.
synchronized (this) {
this.notify();
}
But I could be wrong, since Java is not my primary playground. Perhaps there is a reason this is done. If you can enlighten me as to what the developer was thinking, I would appreciate it.
It certainly is not pointless, you can have another thread that has a reference to the object containing the above code doing
synchronized(foo) {
foo.wait();
}
in order to be woken up when something happens. Though, in many cases it's considered good practice to synchronize on an internal/private lock object instead of this.
However, only doing a .notify() within the synchronization block could be quite wrong - you usually have some work to do and notify when it's done, which in normal cases also needs to be done atomically in regards to other threads. We'd have to see more code to determine whether it really is wrong.
If that is all that is in the synchonized block then it is an antipattern, the point of synchronizing is to do something within the block, setting some condition, then call notify or notifyAll to wake up one or more waiting threads.
When you use wait and notify you have to use a condition variable, see this Oracle tutorial:
Note: Always invoke wait inside a loop that tests for the condition being waited for. Don't assume that the interrupt was for the particular condition you were waiting for, or that the condition is still true.
You shouldn't assume you received a notification just because a thread exited from a call to Object#wait, for multiple reasons:
When calling the version of wait that takes a timeout value there's no way to know whether wait ended due to receiving a notification or due to timing out.
You have to allow for the possibility that a Thread can wake up from waiting without having received a notification (the "spurious wakeup").
The waiting thread that receives a notification still has to reacquire the lock it gave up when it started waiting, there is no atomic linking of these two events; in the interval between being notified and reacquiring the lock another thread can act and possibly change the state of the system so that the notification is now invalid.
You can have a case where the notifying thread acts before any thread is waiting so that the notification has no effect. Assuming one thread will enter a wait before the other thread will notify is dangerous, if you're wrong the waiting thread will hang indefinitely.
So a notification by itself is not good enough, you end up guessing about whether a notification happened when the wait/notify API doesn't give you enough information to know what's going on. Even if other work the notifying thread is doing doesn't require synchronization, updating the condition variable does; there should at least be an update of the shared condition variable in the synchronized block.
This is perfectly fine. According to the Java 6 Object#notify() api documentation:
This method should only be called by a thread that is the owner of this object's monitor.
This is generally not a anti-pattern, if you still want to use intrinsic locks. Some may regard this as an anti pattern, as the new explicit locks from java.util.concurrent are more fine grained.
But your code is still valid. For instance, such code can be found in a blocking queue, when an blocking operation has succeeded and another waiting thread should be notified. Note however that concurrency issues are highly dependent on the usage and the surrounding code, so your simple snippet is not that meaningful.
The Java API documentation for Object.notify() states that the method "should only be called by a thread that is the owner of this object's monitor". So the use could be legitimate depending upon the surrounding context.

Categories

Resources