Javadoc and some answers(Threads - Why a Lock has to be followed by try and finally) state that:
In most cases, the following idiom should be used:
Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
I have seen examples of this idiom in standard Java libraries.
This is my example of using it. Fields acc1 and acc2 represent a wellknown example of bank accounts. The main constraint is the sum of values of acc's - it should be 0.
public class Main {
int acc1;
int acc2;
ReadWriteLock lock = new ReentrantReadWriteLock();
public int readSum() {
lock.readLock().lock();
try {
return acc1 + acc2;
} finally {
lock.readLock().unlock();
}
}
public void transfer() {
lock.writeLock().lock();
try {
acc1--; // constraint is corrupted
// exception throwed here
acc2++; // constraint is regained
} finally {
lock.writeLock().unlock();
}
}
}
I understand using the idiom at read case: if exception thrown in read method other threads still can read/write consistent resource. But if excteption thrown in write method read methods can read inconsisted resource.
Why reading inconsistent values is more preferable then infinity lock waiting?
Why Java libraries authors prefer this behavior?
You can rollback or give some warning info to user but you can do nothing if program is blocked.
I agree with what you talk about data consistency. It's dangerous to unlock in finally part without any rollback operation or warning.
You are mixing up different concepts here. There is:
Locking, and the preventing of dead-locks, and then
Another dimension, lets call it "data integrity".
The point: those two are basically orthogonal. The fact that you are addressing one of them doesn't magically resolve the other for you!
Even when you look at your own example, you find that you put a try/finally there. But there is no catch there!
at all cost
Meaning: if some exception is thrown, that exception is still thrown, and some catcher will have to deal with it.
In other words: if your "locked" code can run into exceptions, then it is your responsibility to handle that in the way that makes the most sense.
And, from a "systems" view: when you got an indefinite lock, that will sooner or later degrade your whole system. If you run into that exception once, then you will run into it more often. So, chances are, that you will run out of threads/locks soon; and your whole application will be affected. That is exactly the kind of problem that can take down a distributed infrastructure - one component stopping to process incoming requests.
Long story short: infinite lock-waiting is something that you want to prevent, because it can seriously impact the ability of your application to function!
Finally: of course, this is about balancing of different requirements. But, example: assume your online shop looses the information that you just deleted an item from your shopping cart. Yes, that is annoying for the customer. But compare that to: the whole online shopping application stops handling requests; because of locking issues. Which problem will hurt your business more?
Related
I've inherited some code and there is nobody of the original developers left. The code uses heavily CompletableFuture, and it's the first time I use it, so I'm still trying to wrap my head around it. As I understand it, a (Completable)Future is typically used with some multithreading mechanism that will allow us to do some other thing while a time consuming task is executing, and then simply fetch its result via the Future. As in the javadoc:
interface ArchiveSearcher { String search(String target); }
class App {
ExecutorService executor = ...
ArchiveSearcher searcher = ...
void showSearch(final String target) throws InterruptedException {
Future<String> future = executor.submit(new Callable<String>() {
public String call() {
return searcher.search(target);
}});
displayOtherThings(); // do other things while searching
try {
displayText(future.get()); // use future
} catch (ExecutionException ex) { cleanup(); return; }
}
}
However, in this application that I've inherited, the following pattern that doesn't use any multithreading appears a bunch of times:
public Object serve(Object input) throws ExecutionException, InterruptedException {
CompletableFuture<Object> result = delegate1(input);
return result.get();
}
private CompletableFuture<Object> delegate1(Object input) {
// Do things
return delegate2(input);
}
private CompletableFuture<Object> delegate2(Object input) {
return CompletableFuture.completedFuture(new Object());
}
To me, this is equivalent to:
public Object serve(Object input) {
Object result = delegate1(input);
return result;
}
private Object delegate1(Object input) {
// Do things
return delegate2(input);
}
private Object delegate2(Object input) {
return new Object();
}
Of course the code is much more complex, and returns exceptionallyCompletedFuture in case of error, but there are is Callable, no Runnable, no Executor, no supplyAsync() no sign of multithreading. What am I missing? What's the point of using a Future in a singled-threaded context?
Futures are critical for situations where there is asynchronous programming. One of the biggest advantages of asynchronous programming is it allows you to write very efficient code with a single thread.
Furthermore, futures tend to be an all-or-nothing proposition. If you want to write asynchronous code you have to do so from top to bottom, even if not every method does something asynchronous.
For example, consider you want to write a single threaded HTTP server like twisted or express. The top level of your server (very liberal pseudocode here) might look something like:
while (true) {
if (serverSocket.ready()) {
connection = serverSocket.accept();
futures.add(server.serve(connection));
}
for (Future future : futures) {
if (future.isDone()) {
Object result = future.get();
sendResult(result);
}
}
//Some kind of select-style wait here
}
There is only one thread but any time an operation happens that would normally require a wait (reading from database, file, reading in the request, etc.) it uses futures and doesn't block the one thread so you have a highly performant single threaded HTTP server.
Now, imagine what would happen if the highest level of your application was like the above and at some point some request at a very low level had to read something from a file. That file read would generate a future. If all of your middle layers in between didn't handle futures then you would have to block and it would defeat the purpose. This is why I say futures tend to be all-or-nothing.
So my guess is either:
Your friend does something asynchronous currently and you haven't caught it yet (does he ever read from a file or database or anything? If so, is he blocking?).
He was planning on someday doing something asynchronous and wanted to plan for it.
He spent a lot of time in other asynchronous frameworks and grew to like the style even if he isn't using it correctly.
Yes, for now there is no multithreading used in that code. Looks like there was an intention to write single-threaded code in such a way that if developer later decides to use multithreading then only
delegate2()
method should be modified.
ExecutorService implementations typically manage threads. I've used the ThreadPoolExecutor, which does exactly that. You commented out which ExecutorService your code uses.
The main point of asynchronous code is to defer the continuation code.
The most common scenario is I/O, where instead of waiting for an operation to finish, you say "do your thing and notify me when you're finished", or more commonly, "do your thing and do this when you're finished".
This doesn't imply threads at all. Reading from any device, be it a network card or a hard drive, usually has some sort of signal or interrupt sent from the device to the CPU. You could use the CPU in the meantime. The "notify me" is more common in lower-level code, where you implement a dispatching loop or scheduler; the "do this" is more common in higher-level code, where you use an established library or framework that dispatches and/or schedules for you.
Less common scenarios include deferring execution without blocking a thread (think of a timer versus Thread.sleep()) and splitting work. Actually, splitting work is very common with multiple threads, where you can improve performance with a bit of overhead, but not so much with a single thread, where the overhead is just, well, overhead.
The code you provide as an example that just builds completed CompletableFutures, whether successfully or exceptionally, is a part of the overhead of asynchronous code that isn't really asynchronous. That is, you must still follow a defined async style, which in this case requires a small amount of memory allocation for results, even if you can provide results immediately.
This may become noticeable on thousands of calls per second, or hundreds of calls per second per thread with dozens of threads.
Sometimes, you can optimize by having predefined completed futures for e.g. null, 0, 1, -1, an empty array/list/stream, or any other very common or even fixed result you may have specifically in your domain. A similar approach is to cache a wrapping future, not just the result, while the result remains the same. But I suggest you first profile before going this way, you may end up optimizing prematurely something that most probably is not a bottleneck.
This great article about best practices for handling interrupts mentions the following:
Sometimes it is necessary to do some amount of cleanup before propagating the exception. In this case, you can catch InterruptedException, perform the cleanup, and then rethrow the exception.
He then goes on to give an example of a method that catches InterruptedException, does a couple lines of cleanup, and then propagates the exception onward.
His small example makes perfect sense, but let's say I have a much longer interruptible method, whose task is not so simple, and it must be performed atomically. In other words, the amount of 'cleanup' it would need to perform when interrupted is substantial. Is this acceptable? If so, could I be cheeky and just catch the interrupt, perform all of the method's normal workflow (pretend it's 'cleanup'), and then propagate the interrupt at the very end?
In other words, I get that it's important to properly handle and propagate interrupts; my question is, how important is it to handle interrupts in a timely manner, and what counts as 'timely'?
Here's the example (real world) scenario where I'm coming from: I have a thread listening to a message queue; handling each message involves multiple HTTP calls and expensive DB operations, and, as currently (unfortunately) designed, these operations must all be performed atomically. Can I define my thread's interrupt-handling behavior to be: 'when interrupted, finish everything you're doing as normal before propagating the interrupt', or is this stretching the definition of 'cleanup' a little too much?
I don't think there is any useful notion of "too little" or "too much" cleanup. Certainly there is no general way to decide that you have done too little or too much.
Specifically ...
Can I define my thread's interrupt-handling behavior to be: 'when interrupted, finish everything you're doing as normal before propagating the interrupt', or is this stretching the definition of 'cleanup' a little too much?
There's no definite answer to this. If it makes sense (e.g. this behaviour is required), then it would be correct to do that. Whether you call it "cleanup" or not is irrelevant.
On the other hand, one of the common use-cases of Java interrupts is to signal to some part of the application to stop what ever it is doing because, for example:
the server is shutting down, or
the requested action is taking too long, or
the client that made the request has "gone away", and there is no other reason to complete the request.
In such cases, "finish everything as normal" may be the wrong strategy, especially if that is going to be expensive. (Or it may be the right strategy; for example, if there is no reliable way to back out of the sequence of actions that need to be done atomically.)
In short ... we can't tell you whether this is the right thing to do.
In other words, I get that it's important to properly handle and propagate interrupts; my question is, how important is it to handle interrupts in a timely manner, and what counts as 'timely'?
Again. These are questions that only make sense (and can only be answered) in the context of your application. It depends ...
But I don't think that this (cleanup) is restricted to interrupts. Consider the example in the article:
public class PlayerMatcher {
private PlayerSource players;
public PlayerMatcher(PlayerSource players) {
this.players = players;
}
public void matchPlayers() throws InterruptedException {
Player playerOne, playerTwo;
try {
while (true) {
playerOne = playerTwo = null;
// Wait for two players to arrive and start a new game
playerOne = players.waitForPlayer(); // could throw IE
playerTwo = players.waitForPlayer(); // could throw IE
startNewGame(playerOne, playerTwo);
}
}
catch (InterruptedException e) {
// If we got one player and were interrupted, put that player back
if (playerOne != null)
players.addFirst(playerOne);
// Then propagate the exception
throw e;
}
}
}
What happens (for example) if waitForPlayers or startNewGame could throw some other exception (checked or unchecked)? In that case, you could end up with lost players ... just like if you had an InterruptedException.
My point ... is that if you are concerned about making the code resilient in general (or "atomic") then it would be better to use a finally block to do the recovery; e.g.
finally {
// Make sure that we *always* put the players back
if (playerOne != null)
players.addFirst(playerOne);
if (playerTwo != null)
players.addFirst(playerTwo);
}
And if you need to do atomic operations that also entail changing state outside of the JVM and/or "the application" ... then even finally is not enough. There are some situations where code in a finally block won't be executed; e.g. if the JVM crashes or is terminated by System.exit(). (This is #EJP's point ...)
The approach you describe is sometimes referred to as "entering 'lame duck' mode", wherein you'll finish what you've already started but won't accept or initiate any new work.
It's fine as long as you document it, so that callers know what to expect. Encountering an InterruptedException means that some upstream caller wants to terminate the thread's activity, but safety trumps responsiveness. If you believe that these operations must all complete together (to the best of your ability), and stopping the unit of work with only part of it done would violate some requirement, then you are in your right to adhere to those requirements and put them above the implied requirement for timely cooperation with an interruption request.
Ideally, you'd cease any further progress with the transaction and attempt to roll back what you've already completed. However, there's subtlety in that design; you could be far enough along that just finishing the transaction would be faster than rolling back your nearly-complete accomplishments.
Again, the key here is documentation. If you document the behavior and find that your callers complain, then you have to push back on the competing requirement for transactional atomicity.
The end of that same article discusses "noncancelable tasks", which finish what they're doing (even if it may take a long time) before responding to the interruption. It sounds like that's what you have.
You don't necessarily have to abort what you're doing immediately, but you should set a flag to remember that an interrupt was requested, then re-throw the InterruptedException later when the atomic work is done.
No. What if you get interrupted again? If you need a method to be atomic you have much bigger problems than propagating exceptions.
Note: I'm not looking for workarounds; I'm sure I can find other methods if necessary. I simply feel like I'm missing something fundamental or quirky and I want to know what I'm missing. Or if there is a way to use the debugger to get more info that would be nice too. Thanks!
I'm having an issue with use of synchronized. I'm receiving deadlock but it seems utterly impossible. I've placed print statements before each and every synchronized call, just inside each call, and just before exiting so I can see who all holds which synchronized objects. I'm finding that it will not go inside one of my synchronized calls even though no one currently holds the lock on the object. Are there some kind of quirks that I'm missing or illegal nesting operations? Here's the jist of what I am doing.
Oh yeah, and the oddest thing is that removing the two "busyFlagObject" synchronizations makes it work fine...
Thread 1:
public void DrawFunction()
{
synchronized(drawObject)
{
...
// Hangs here though nobody has a lock on this object
synchronized(animationObject)
{
}
}
}
Thread 2:
public void AnotherFunction()
{
synchronized(busyFlagObject)
{
// Calls a function that also uses this same Synchronized call
synchronized(busyFlagObject)
{
// Calls another function that uses another Synchronized call
// Hangs here waiting for the draw function to complete which it SHOULD
// be able to do no problem.
synchronized(drawObject)
{
}
// Never gets to this one assuming the Log statements don't
// buffer and aren't flushed but still shouldn't be a problem anyway.
synchronized(animationObject)
{
}
}
}
}
Run your app under the debugger or use "jstack" from the JDK tools. That will show you directly which threads wait for locks and which hold locks, so we don't have to guess where your problem is :-)
That said, you mention you synchronize on Boolean. Keep in mind that the class is intended to only have two instances, and many things (particularly boxing) will implicitly change your Boolean instance to the "shared" value. Are you sure your lock objects are not the same instance? You might consider using new Object() as your monitor object.
It's worth noting that this isn't the only place that this can happen and there's a good entry on this problem in Java Concurrency in Practice, specifically with string interning, that I'm failing to find a link to at the moment. Don't use a type that isn't under your control as something it wasn't intended to do :-)
I have a critical section of my (Java) code which basically goes like the snippet below. They're coming in from a nio server.
void messageReceived(User user, Message message) {
synchronized(entryLock) {
userRegistry.updateLastMessageReceived(user,time());
server.receive(user,message);
}
}
However, a high percentage of my messages are not going to change the server state, really. They're merely the client saying "hello, I'm still here". I really don't want to have to make that inside the synchronization block.
I could use a synchronous map or something like that, but it's still going to incur a synchronization penalty.
What I would really like to do is to have something like a drop box, like this
void messageReceived(User user, Message message) {
dropbox.add(new UserReceived(user,time());
if(message.getType() != message.TYPE_KEPT_ALIVE) {
synchronized(entryLock) {
server.receive(user,message);
}
}
}
I have a cleanup routine to automatically put clients that aren't active to sleep. So instead of synchronizing on every kept alive message to update the registry, the cleanup routine can simply compile the kept alive messages in a single synchronization block.
So naturally, reconigizing a need for this, the first thing I did was start making a solution. Then I decided this was a non-trivial class, and a problem that was more than likely fairly common. so here I am.
tl;dr Is there a Java library or other solution I can use to facilitate atomically adding to a list of objects in an asynchronous manner? Collecting from the list in an asychronous manner is not required. I just don't want to synchronize on every add to the list.
ConcurrentLinkedQueue claims to be:
This implementation employs an efficient "wait-free" algorithm based on one described in Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms by Maged M. Michael and Michael L. Scott.
I'm not sure what the quotes on "wait-free" entail but the Concurrent* classes are good places to look for structures like you're looking for.
You might also be interested in the following: Effective Concurrency: Lock-Free Code — A False Sense of Security. It talks about how hard these things are to get right, even for experts.
Well, there are few things you must bear in mind.
First, there is very little "synchronization cost" if there is little contention (more than one thread trying to enter the synchronized block at the same time).
Second, if there is contention, you're going to incur some cost no matter what technique you're using. Paul is right about ConcurrentLinkedQueue and the "wait-free" means that thread concurrency control is not done using locks, but still, you will always pay some price for contention. You may also want to look at ConcurrentHashMap because I'm not sure a list is what you're looking for. Using both classes is quite simple and common.
If you want to be more adventurous, you might find some non-locking synchronization primitives in java.util.concurrent.atomic.
One thing we could do is to use a simple ArrayList for keep-alive messages:
Keep adding to this list whenever each keep-alive message comes.
The other thread would synch on a lock X and read and process
keep-alives. Note that this thread is not removing from list only
reading/copying.
Finally in messageReceived itself you check if the list has grown
say beyond 1000, in which case you synch on the lock X and clear the
list.
List keepAliveList = new ArrayList();
void messageReceived(User user, Message message) {
if(message.getType() == message.TYPE_KEPT_ALIVE) {
if(keepAliveList.size() > THRESHOLD) {
synchronized(X) {
processList.addAll(list);
list.clear();
}
}
keepAliveList.add(message);
}
}
//on another thread
void checkKeepAlives() {
synchronized(X) {
processList.addAll(list)
}
processKeepAlives(processList);
}
I notice that NetBeans is warning me about using Thread.sleep() in a while loop in my Java code, so I've done some research on the subject. It seems primarily the issue is one of performance, where your while condition may become true while the counter is still sleeping, thus wasting wall-clock time as you wait for the next iteration. This all makes perfect sense.
My application has a need to contact a remote system and periodically poll for the state of an operation, waiting until the operation is complete before sending the next request. At the moment the code logically does this:
String state = get state via RPC call
while (!state.equals("complete")) {
Thread.sleep(10000); // Wait 10 seconds
state = {update state via RPC call}
}
Given that the circumstance is checking a remote operation (which is a somewhat expensive process, in that it runs for several seconds), is this a valid use of Thread.sleep() in a while loop? Is there a better way to structure this logic? I've seen some examples where I could use a Timer class, but I fail to see the benefit, as it still seems to boil down to the same straightforward logic above, but with a lot more complexity thrown in.
Bear in mind that the remote system in this case is neither under my direct control, nor is it written in Java, so changing that end to be more "cooperative" in this scenario is not an option. My only option for updating my application's value for state is to create and send an XML message, receive a response, parse it, and then extract the piece of information I need.
Any suggestions or comments would be most welcome.
Unless your remote system can issue an event or otherwise notify you asynchronously, I don't think the above is at all unreasonable. You need to balance your sleep() time vs. the time/load that the RPC call makes, but I think that's the only issue and the above doesn't seem of concern at all.
Without being able to change the remote end to provide a "push" notification that it is done with its long-running process, that's about as well as you're going to be able to do. As long as the Thread.sleep time is long compared to the cost of polling, you should be OK.
You should (almost) never use sleep since its very inefficient and its not a good practice. Always use locks and condition variables where threads signal each other. See Mike Dahlin's Coding Standards for Programming with threads
A template is:
public class Foo{
private Lock lock;
private Condition c1;
private Condition c2;
public Foo()
{
lock = new SimpleLock();
c1 = lock.newCondition();
c2 = lock.newCondition();
...
}
public void doIt()
{
try{
lock.lock();
...
while(...){
c1.awaitUninterruptibly();
}
...
c2.signal();
}
finally{
lock.unlock();
}
}
}