Similar to the question I posted yesterday, I have this problem that I just can't understand. The code is pretty simple and should (I think) generate a deadlock. I even reduced the number of accounts to 2, to increase the probability of deadlocks.
The code is really easy to understand but to put some context. I have a bank with accounts and I'm doing lots of transfers between accounts. The transfer method should generate a deadlock. Why isn't that happening?
I can only think that the code is running way too fast, but that seems improbable to happen all the time.
Here's the whole code:
http://pastebin.com/HWJpuT38
Problem is on this line:
mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));
Basically, there is only one Account object, but lots of references to it. Thus you're only ever locking on a single object.
If you create lots of different Account objects, you should be able to see the deadlock quite quickly.
The only place where you have a 'contested' resource is where you synchronize on fromaccount and then on toaccount - everything else depends on one lock only.
If you had another method which synchronized on toaccount and then on fromaccount you might have a chance of causing deadlock, but as the code currently is it should be perfectly well-behaved.
I think you need to add some sort of sleep to your loop in AccountTransferRunnable otherwise the Scheduler will run the thread until end before starting the other one.
With a Sleep you will give the Scheduler the chance to switch to the other thread will the first one is still running, which will give your code the chance to run into a deadlock.
mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#nCopies%28int,%20java.lang.Object%29
You end up with a list of 2 references to the same object.
That object can only be locked by one thread at a time. You can never have a deadlock.
I assume you wanted to initialize mAccounts with 2 different instances of Account class.
Related
I know synchronized keyword makes method run only on single class at a time. But here is the problem.
I have a database class with methods e.g. insertAccount, updateSetting, etc. If I make insertAccount, updateSetting synchronized, each of them will be able to run only on one thread at a time.
If there was one method for whole database, it would be great, but there are not one. If one thread calls insertAccount and another thread calls updateSetting at the same time, it will go bad, right?
Because only one of these methods can be run at any time. So what do I do?
Is there a way to apply something like synchronized to the whole class? So that if 1st thread calls insertAccount and 2nd thread calls updateSetting at the same time, 2nd thread has to wait until 1st thread finishes accessing database.
The real answer here: step back and do some studying. You should not be using synchronized here, but rather look into a lock object that a reader/writer needs to acquire prior turning to that "DB class". See here for more information.
On the other hand, you should understand what transactions are, and how your database supports those. Meaning: there are different kinds of problems; and the different layers (application code, database) have different responsibilities.
You see, using "trial and error" isn't an approach that will work out here. You should spend some serious time studying the underlying concepts. Otherwise you are risking to damage your data set; and worse: you risk writing code that works fine most of the time; but fails in obscure ways "randomly". Because that is what happens when multiple threads manipulate shared data in an uncontrolled manner.
You misunderstood how synchronized work.
If you mark two method of class by synchronized only one of them could be executed at any moment of time (except if you invoke wait).
Also note that if you have several instances of this class you can execute methods of different instances simultaneously.
#Test(singleThreaded = true) Use above annotation above class and its tests will be run using a single thread even though you have used parallel="methods" in your testng.xml file
I am learning multithreading, and I have a little question.
When I am sharing some variable between threads (ArrayList, or something other like double, float), should it be lcoked by the same object in read/write? I mean, when 1 thread is setting variable value, can another read at same time withoud any problems? Or should it be locked by same object, and force thread to wait with reading, until its changed by another thread?
All access to shared state must be guarded by the same lock, both reads and writes. A read operation must wait for the write operation to release the lock.
As a special case, if all you would to inside your synchronized blocks amounts to exactly one read or write operation, then you may dispense with the synchronized block and mark the variable as volatile.
Short: It depends.
Longer:
There is many "correct answer" for each different scenarios. (and that makes programming fun)
Do the value to be read have to be "latest"?
Do the value to be written have let all reader known?
Should I take care any race-condition if two threads write?
Will there be any issue if old/previous value being read?
What is the correct behaviour?
Do it really need it to be correct ? (yes, sometime you don't care for good)
tl;dr
For example, not all threaded programming need "always correct"
sometime you tradeoff correctness with performance (e.g. log or progress counter)
sometime reading old value is just fine
sometime you need eventually correct (e.g. in map-reduce, nobody nor synchronized is right until all done)
in some cases, correct is mandatory for every moment (e.g. your bank account balance)
in write-once, read-only it doesn't matter.
sometime threads in groups with complex cases.
sometime many small, independent lock run faster, but sometime flat global lock is faster
and many many other possible cases
Here is my suggestion: If you are learning, you should thing "why should I need a lock?" and "why a lock can help in DIFFERENT cases?" (not just the given sample from textbook), "will if fail or what could happen if a lock is missing?"
If all threads are reading, you do not need to synchronize.
If one or more threads are reading and one or more are writing you will need to synchronize somehow. If the collection is small you can use synchronized. You can either add a synchronized block around the accesses to the collection, synchronized the methods that access the collection or use a concurrent threadsafe collection (for example, Vector).
If you have a large collection and you want to allow shared reading but exclusive writing you need to use a ReadWriteLock. See here for the JavaDoc and an exact description of what you want with examples:
ReentrantReadWriteLock
Note that this question is pretty common and there are plenty of similar examples on this site.
I have more than just a basic understanding of locks and synchronized blocks. However, as far as i know, they just ensure that a single thread has access to some data at a time.
What i need is a little bit different. Lets say i have a String. One and only one thread my change it (assign some value to it), and lets assume this operation takes a lot of time - 3 seconds.
A lot of other threads need to read the value of this String, and do some operations (execute a block of code) with the assumption that the value remains unchanged until the whole block executes. Lets assume that this block takes 5 secs to execute.
So, the "writer" thread must not update the String while there are threads using/reading it, and the "reader" threads must wait for an update (by the "writer") to finish before starting to use it.
I could solve this with a lock if there was only 1 "writer" and 1 "reader", but how can i do this now that there is 1 "writer" and N "readers". Note that many "readers" may access the data at the same time.
By the way, it is kind of hard to provide code, since it is hundreds of line, includes internet access, database access...
I know i can avoid this problem by changing my implementation but i have reasons to prefer this implementation - and it's not i'm too lazy to change it.
What you are looking for is a ReadWriteLock
. Where multiple threads can read at the same time. A write is blocked until the reading threads finish. And reads are blocked until the writing thread finishes.
If operations take that long, you are doing something wrong. The right method is to calculate the new data, however long it takes, without affecting the old data, and then replacing the old with the new data in one go. And destroying the old data only when everyone using it is finished with it.
I have 2 threads, one to take Orders and the other one to distribute the orders.
My first thread must be able to get the orders gradually one by one from a file and display it in a JTextArea-1, while this is happening the other thread should be able to remove one order at a time from JTextArea-1 and paste it to another JTextArea-2.
I have created 2 threads and used MVC pattern (with 2 views and 1 model). The Threads are both displaying the values in the JTEXTAREA's at the same time which is not acceptable. How can i solve this issue?
I should have a minimum 5 seconds delay between the removing from JTextArea-1 and pasting into JTextArea-2. kindly help.
Fundamental lack of comprehension of concurrency alert!
This is not the appropriate way to deal with your problem, which probably doesn't even need threads in the first place.
But if you insist on using threads, what you want is a semaphore to block one thread until a condition for the other thread to act exists. A "FIFO blocking queue" would be appropriate here as well.
Using pauses and timing with concurrency is not effective as it is a non-deterministic system, and only lead to even more subtle failure scenarios.
You could simply just add a synchronized call that logs the text so that only 1 thread can perform that at one time.
I have a piece of code that looks like this:
Algorithm a = null;
while(a == null)
{
a = grid.getAlgorithm();
}
getAlgorithm() in my Grid class returns some subtype of Algorithm depending on what the user chooses from some options.
My problem is that even after an algorithm is selected, the loop never terminates. However, that's not the tricky bit, if I simply place a System.out.println("Got here"); after my call to getAlgorithm(), the program runs perfectly fine and the loop terminates as intended.
My question is: why does adding that magic print statement suddenly make the loop terminate?
Moreover, this issue first came up when I started using my new laptop, I doubt that's related, but I figured it would be worth mentioning.
Edit: The program in question is NOT multithreaded. The code for getAlgorithm() is:
public Algorithm getAlgorithm ()
{
return algorithm;
}
Where algorithm is initially null, but will change value upon some user input.
I believe the issue has to deal with how grid.getAlgorithm is executed. If there is very little cost associated with executing the method, then your while loop will cycle very quickly as long the method continues to return null. That is often referred to as a busy wait.
Now it sounds like your new laptop is encountering a starvation issue which didn't manifest on your old computer. It is hard to say why but if you look at the link I included above, the Wikipedia article does indicate that busy waits do have unpredictable behavior. Maybe your old computer handles user IO better than your new laptop. Regardless, on your new laptop, that loop is taking resources away from whatever is handling your user IO hence it is starving the process that is responsible for breaking the loop.
You are doing active polling. This is a bad practice. You should at least let the polling thread sleep (with Thread.sleep). Since println does some io, it probably does just that. If your app is not multithreaded it is unlikely to work at all.
If this loop is to wait for user input in a GUI then ouch. Bad, bad idea and even with Thread.sleep() added I'd never recommend it. Instead, you most likely want to register an event listener on the component in question, and only have the validation code fire off when the contents change.
It's more than likely you're program is locking up because you've reached some form of deadlock more than anything else, especially if your application is multithreaded. Rather than try to solve this issue and hack your way round it, I'd seriously consider redesigning how this part of the application works.
You should check getAlgorithm(), there must be something wrong in the method.
There are two scenarios:
Your code is really not meant to be multi-threaded. In this case you need to insert some sort of user input in the loop. Otherwise you might as well leave it as Algorithm a = grid.getAlgorithm(); and prevent the infinite loop.
Your code is multi-threaded in which case you have some sort of 'visibility' problem. Go to Atomicity, Visibility and Ordering or read Java Concurrency in Practice to learn more about visibility. Essentially it means that without some sort of synchronization between threads, the thread you are looping in may never find out that the value has changed due to optimizations the JVM may perform.
You did not mention any context around how this code is run. If it is a console based application and you started from a 'main' function, you would know if there was multi-threading. I am assuming this is not the case since you say there is no multithreading. Another option would be that this is a swing application in which case you should read Multithreaded Swing Applications. It might be a web application in which case a similar case to swing might apply.
In any case you could always debug the application to see which thread is writing to the 'algorithm' variable, then see which thread is reading from it.
I hope this is helpful. In any case, you may find more help if you give a little more context in your question. Especially for a question with such an intriguing title as 'Weird Java problem, while loop termination'.