I am sorting my list data after every modification but since several threads could call the sorting method block, I decided to put it in a synchronized block. My code is as shown below. Problem is, despute the synchronized block, I am still getting 'ConcurrentModificationExceptio' on the line Collections.sort(storageBckupData.get(msg.what).getTotalItems(),new BackupDataComparator());. Any reason why I keep getting this?
class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
default:
synchronized(LOCK) {
while(inUse) {
try {
LOCK.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
inUse = true;
Collections.sort(storageBckupData.get(msg.what).getTotalItems(),new BackupDataComparator());
inUse = false;
LOCK.notifyAll();
}
notifyDataSetChanged();
super.handleMessage(msg);
}
}
}
ConcurrentModificationException is not about whether you have synchronized or not, its when the collection detects a modification being done concurrently with something that does not allow it. For example you might have (somewhere else in your code which you are not showing) an iterator going through the list of items. Its about protecting the integrity of the collection.
What is happening in the other thread? Is it going through the list in parallel?
Draw a Sequence Diagram of both threads and you should clearly find what one thread is doing in parallel of the other.
Also, do you actually need to do that locking? You can get a synchronized collection through methods such as Collections.synchronizedList()
Why don't you use an appropriate data structure that takes care of sorting more efficiently? If each item is unique you could use a SortedSet implementation such as TreeSet.
Related
Okay so this is the code. It basically has three classes. One of them is increasing a value and the other one decreasing with an endless loop. But when the value goes over or under a specific limit, it has to stop. But since both of the functions have notifyAll, it wakes the other functions as well so even if it is at the limit, it keeps going. How can I solve this problem? Thanks in advance.
First Class (increasing and with Thread):
public class Producer extends Thread{
private Counter counter;
public Producer(Counter counter) {
// TODO Auto-generated constructor stub
this.counter=counter;
}
#Override
public void run() {
// TODO Auto-generated method stub
//super.run();
for(;;) {
try {
counter.increase();
sleep(100);
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("Producer:"+e.getMessage());
}
}
}
The second class (decreasing with Runnable):
public class Consumer implements Runnable{
private Counter counter;
public Consumer(Counter counter) {
// TODO Auto-generated constructor stub
this.counter=counter;
}
#Override
public void run() {
// TODO Auto-generated method stub
//super.run();
for(;;) {
try {
counter.decrease();
Thread.currentThread().sleep(100);
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("Consumer:"+e.getMessage());
}
}
}
}
Third class which contains the functions:
import java.util.Random;
public class Counter {
private int counter;
private Random ran;
public Counter() {
//super();
counter=0;
ran= new Random();
}
public synchronized void increase() {
int number=ran.nextInt(5);
if(counter+number>=100 ) {
System.out.println("Producer is stopping, value is: "+counter);
System.out.println("The generated number is: "+number);
try {
wait();
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("error in increasing mehtod"+e.getMessage());
}
}
counter = counter+number;
notifyAll();
System.out.println("Prdoucer increase: "+counter);
}
public synchronized void decrease() {
int number= ran.nextInt(5);
if(counter-number<0) {
System.out.println("Consumer is stopping, value is: "+counter);
System.out.println("The generated number is: "+number);
try {
wait();
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("error in decreasing mehtod"+e.getMessage());
}
}
counter = counter-number;
notifyAll();
System.out.println("Consumer decrease: "+counter);
}
}
Read about spurious notifies. A thread can be notified even without explicit call to notify()/notifyAll(). So after each notify the thread must check if it was indeed notified, and be ready to find out it was notified in vain.
.How to use notifyAll() for a specific thread.
You don't. That's not what notifyAll() is for, and it's not what notify() is for either.
You use notify() and/or notifyAll() to notify other threads that some particular thing has changed or happened. You use notify() when it's guaranteed that any single thread that catches the notification will be able to deal with whatever it was that changed or happened. You use notifyAll() otherwise.
In neither case does the caller get to specify which thread or threads should be notified. The system will randomly chose any single thread that happens to be waiting in an o.wait() call if you call o.notify() for the same object o, or it will notify all of the threads that happen to be waiting in o.wait() if you call o.notifyAll(). It won't do anything for threads that aren't already in an o.wait() call at the moment when o.notify() or o.notifyAll() was called.
It's up to you to write code that exploits those functions to your advantage. There's plenty of examples and tutorials out there for how to do that. My personal favorite: https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
Also note: Correctly usage of notify() and notifyAll() is somewhat tricky. It's tricky for you to write it correctly, and it's tricky for other people who want to read and understand your code.
If you think you need notify() or notifyAll() the first thing you should do is consider whether or not you could use some higher-level class that encapsulates the notify/wait behavior. E.g., for a "producer/consumer" architecture, you might consider using a BlockingQueue.
The code below is my run method. This stat status does not take the newly updated status from my stop method.
#Override
public void run() {
synchronized (this) {
while (!stat) {
try {
this.wait();
} catch (InterruptedException ex) {
Logger.getLogger(TrafficLightSimulator.class.getName()).log(Level.SEVERE, null, ex);
} }
}
}
In the above code, the program does not enter while loop. It is because the stat boolean new changed value from the stop method is not taken in run method.
This is my new stop
public void stop() {
synchronized(this) {
this.stopStat = false;
this.notifyAll();
}
}
I even defined the stat as the volatile boolean variable. However, this also does not seem to work.
While you have the "waiting" part correct, your "setting" part is missing some important parts.
The first part that is missing is the lock:
public void stop() {
synchronized(this) {
this.stat = true;
}
}
This lock makes sure that only 1 thread can change/access it at the same time, as is required by the Java memory model. Without this lock (and without volatile), Java makes no guarantee that changes to this variable are seen by other threads.
The next part that missing is the notifying part, it is important to "wake" up all waiting threads when the condition is changed:
public void stop() {
synchronized(this) {
this.stat = true;
this.notifyAll();
}
}
The last part of your error happens due the fact you are setting the variable to true, while for the code to be inside the while loop, the variable is already true. You probably want to set it to false instead
public void stop() {
synchronized(this) {
this.stat = false;
this.notifyAll();
}
}
Memory visibility isn't an issue here because both the code reading the flag and the code setting the flag are synchronized, holding the same lock. If your code won't enter the while loop it must be that some other thread has the lock.
This is another reason (in addition to the reasons below) to use interrupt instead of wait/notify for this. Interruption doesn't depend on acquiring a lock to work.
Use interrupt for this instead. There's no good reason for your own flag here when one is provided for you, using wait/notify for this is unnecessary and can cause problems since you may need to wait/notify for other reasons.
The Java api docs advise against locking on threads, by the way. That's what join does. Implicit locking doesn't have a way to have different conditions get separate notifications for a lock (the way ReentrantLock does).
For a thread that does things with intermittent sleeps in between, the run method can look like:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
doStuff();
Thread.sleep(1000L);
} catch (InterruptedException e) {
// no need to log this as an error, it's not an error
Thread.currentThread().interrupt();
}
}
}
Real world code uses threadpools where you submit Runnable or Callable tasks, the java.util.concurrent classes expect your code to handle interruption.
We have been looking at a threading error for a while and are not sure how this is possible. Below is a minimized example from our code. There is a cache holding data retrieved from a database (or: "a lengthy synchronous operation", as far as this example is concerned). There is a thread for reloading the cache, while other threads try to query the cache. There is a period of time when the cache is null, waiting to be reloaded. It should not be queryable during this time, and we tried to enforce this by synchronizing the methods that access the cache - both for reading and writing. Yet if you run this class for a while, you will get NPEs in search(). How is this possible?
Java docs state that "it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object".
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CacheMultithreading01 {
private long dt = 1000L;
public static void main(String[] args) {
CacheMultithreading01 cm = new CacheMultithreading01();
cm.demonstrateProblem();
}
void demonstrateProblem() {
QueryableCache cache = new QueryableCache();
runInLoop("Reload", new Runnable() {
#Override
public void run() {
cache.reload();
}
});
runInLoop("Search", new Runnable() {
#Override
public void run() {
cache.search(2);
}
});
// If the third "runInLoop" is commented out, no NPEs
runInLoop("_Clear", new Runnable() {
#Override
public void run() {
cache.clear();
}
});
}
void runInLoop(String threadName, Runnable r) {
new Thread(new Runnable() {
#Override
public synchronized void run() {
while (true) {
try {
r.run();
} catch (Exception e) {
log("Error");
e.printStackTrace();
}
}
}
}, threadName).start();
}
void log(String s) {
System.out.format("%d %s %s\n", System.currentTimeMillis(), Thread
.currentThread().getName(), s);
}
class QueryableCache {
private List<Integer> cache = new ArrayList<>();
public synchronized void reload() {
clear();
slowOp(); // simulate retrieval from database
cache = new ArrayList<>(Arrays.asList(1, 2, 3));
}
public synchronized void clear() {
cache = null;
}
public synchronized Integer search(Integer element) {
if (cache.contains(element))
return element;
else
return null;
}
private void slowOp() {
try {
Thread.sleep(dt);
} catch (InterruptedException e) {
}
}
}
}
//java.lang.NullPointerException
//at examples.multithreading.cache.CacheMultithreading01$QueryableCache.search(CacheMultithreading01.java:73)
//at examples.multithreading.cache.CacheMultithreading01$2.run(CacheMultithreading01.java:26)
//at examples.multithreading.cache.CacheMultithreading01$4.run(CacheMultithreading01.java:44)
//at java.lang.Thread.run(Thread.java:745)
We do not understand why the NPEs can happen even though the code is synchronized. We also do not understand why the NPEs stop happening if we comment out the third call to runInLoop (the one that does cache.clear).
We have also tried to implement locking using a ReentrantReadWriteLock - and the result is the same.
Since you don't have any more advanced locking, you can call clear() and search() consecutively. That will obviously cause a NPE.
Calling reload() and search() won't cause problems, since in reload the cache is cleared, then rebuilt, inside a synchronized block, preventing other (search) operations from being executed in between.
Why is there a clear() method that will leave cache in a "bad" state (which search() doesn't even check for)?
You have to check in the search method if cache is null. Otherwise calling contains on it in search can throw a NullPointerException in the case that you have previously set cache to null in the clear-method.
Synchronization is working as correctly.
The problem is that the method clear puts cache to null. And there is no guarantee that reload method will be called before search.
Also, note that the method reload, it's not releasing the lock. So, when you are waiting for the slowOp to finish, the other methods can't execute.
"There is a period of time when the cache is null, waiting to be reloaded."
This is your problem: clear sets things to null, and then returns, releasing the synchronization lock, allowing someone else to access.
It would be better to make the "new" assignment atomic and not clear().
Assuming that slowOp() needs to return data for the cache (private List<Integer> slowOp()) you retrieve that data before assigning it
ArrayList<Integer> waitingForData = slowOp();
cache = watingForData;
This 'updates' the cache only after the data is available. Assignment is an atomic operation, nothing can access cache while the reference is being updated.
Three different threads invoking clear() search() and reload() of the cache without a definitive interleaving. Since the interleaving doesn't gurantees the the sequence of lock being obtained for the clear() and search() threads there could be chances where the search thread is getting the lock over the object just after the clear() thread. In that case the search would result in the NullPointerException.
You may have to check for the cache equal to null in the search object and may be do a reload() from within the search() method. This would gurantee the search result or return null as applicable.
I've got an ArrayList which is being instantiated and populated on the background thread (I use it to store the Cursor data). At the same time it can be accessed on the main thread and iterated through using foreach. So this obviously may result in throwing an exception.
My question is what's the best practice to make this class field thread-safe without copying it every time or using flags?
class SomeClass {
private final Context mContext;
private List<String> mList = null;
SomeClass(Context context) {
mContext = context;
}
public void populateList() {
new Thread(new Runnable() {
#Override
public void run() {
mList = new ArrayList<>();
Cursor cursor = mContext.getContentResolver().query(
DataProvider.CONTENT_URI, null, null, null, null);
try {
while (cursor.moveToNext()) {
mList.add(cursor.getString(cursor.getColumnIndex(DataProvider.NAME)));
}
} catch (Exception e) {
Log.e("Error", e.getMessage(), e);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}).start();
}
public boolean searchList(String query) { // Invoked on the main thread
if (mList != null) {
for (String name : mList) {
if (name.equals(query) {
return true;
}
}
}
return false;
}
}
In general it is a very bad idea to operate concurrently on a datastructure that is not thread-safe. You have no guarantee that the implementation will not change in the future, which may severly impact the runtime behavior of the application, i.e. java.util.HashMap causes infinite loops when being concurrently modified.
For accessing a List concurrently, Java provides the java.util.concurrent.CopyOnWriteArrayList. Using this implementation will solve your problem in various ways:
it is thread safe, allowing concurrent modifications
iterating over snapshots of the list is not affected by concurrent add operations, allowing concurrently adding and iterating
it's faster than synchronization
Alternatively, if not using a copy of the internal array is a strict requirement (which I can't imagine in your case, the array is rather small as it only contains object references, which can be copied in memory quite efficiently), you may synchronize the access on the map.
But that would require the Map to be initialized properly, otherwise your code may throw a NullPointerException because the order of thread-execution is not guaranteed (you assume the populateList() is started before, so the list gets initialized.
When using a synchronized block, choose the protected block wisely. In case you have the entire content of the run() method in a synchronized block, the reader thread has to wait until the results from the cursor are processed - which may take a while - so you actually loose all concurrency.
If you decide to go for the synchronized block, I'd make the following changes (and I don't claim, they are perfectly correct):
Initialize the list field so we can synchronize access on it:
private List<String> mList = new ArrayList<>(); //initialize the field
Synchronize the modification operation (add). Do not read the data from the cursor inside the synchronization block because if its a low latency operation, the mList could not be read during that operation, blocking all other threads for quite a while.
//mList = new ArrayList<>(); remove that line in your code
String data = cursor.getString(cursor.getColumnIndex(DataProvider.NAME)); //do this before synchronized block!
synchronized(mList){
mList.add(data);
}
The read iteration must be inside the synchronization block, so no element gets added, while being iterated over:
synchronized(mList){
for (String name : mList) {
if (name.equals(query) {
return true;
}
}
}
So when two threads operate on the list, one thread can either add a single element or iterate over the entire list at a time. You have no parallel execution on these parts of the code.
Regarding the synchronized versions of a List (i.e. Vector, Collections.synchronizedList()). Those might be less performant because with synchronization you actually lose prallel execution as only one thread may run the protected blocks at a time. Further, they might still be prone to ConcurrentModificationException, which may even occur in a single thread. It is thrown, if the datastructure is modified between iterator creation and iterator should proceed. So those datastructures won't solve your problem.
I do not recommend manualy synchronization as well, because the risk of simply doing it wrong is too high (synchronizing on the wrong or different monitory, too large synchronization blocks, ...)
TL;DR
use a java.util.concurrent.CopyOnWriteArrayList
Use Collections.synchronizedList(new ArrayList<T>());
Ex:
Collections.synchronizedList(mList);
java synchronized block http://www.tutorialspoint.com/java/java_thread_synchronization.htm
class SomeClass {
private final Context mContext;
private List<String> mList = null;
SomeClass(Context context) {
mContext = context;
}
public void populateList() {
new Thread(new Runnable() {
#Override
public void run() {
synchronized(SomeClass.this){
mList = new ArrayList<>();
Cursor cursor = mContext.getContentResolver().query(
DataProvider.CONTENT_URI, null, null, null, null);
try {
while (cursor.moveToNext()) {
mList.add(cursor.getString(cursor.getColumnIndex(DataProvider.NAME)));
}
} catch (Exception e) {
Log.e("Error", e.getMessage(), e);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}
}).start();
}
public boolean searchList(String query) { // Invoked on the main thread
synchronized(SomeClass.this){
if (mList != null) {
for (String name : mList) {
if (name.equals(query) {
return true;
}
}
}
return false;
}
}
}
You could use a Vector which is the thread-safe equivalent of ArrayList.
EDIT: Thanks to Fildor's comment, I now know this doesn't avoid ConcurrentModificationException from being thrown using multiple threads:
Only single calls will be synchronized. So one add cannot be called while another thread is calling add, for example. But altering the list will cause the CME be thrown while iterating on another thread. You can read the docs of iterator on that topic.
Also interesting:
Why is Java Vector class considered obsolete or deprecated?
Vector vs Collections.synchronizedList(ArrayList)
Long story short: DO NOT use Vector.
I have a Thread that only has to work when a certain circumstance comes in. Otherwise it just iterates over an empty infinite loop:
public void run() {
while(true) {
if(ball != null) {
// do some Calculations
}
}
}
Does it affect the performance when the loop actually does nothing but it has to check if it has to do the calculation every iteration?
Only creating a this Thread when needed is not an option for me, because my class which implements Runnable is a visual object which has be shown all the time.
edit: so is the following a good solution? Or is it better to use a different method (concerning performance)?
private final Object standBy = new Object();
public void run() {
while(true) {
synchronized (standBy) {
while(ball != null) // should I use while or if here?
try{ standBy.wait() }
catch (InterruptedException ie) {}
}
if(ball != null) {
// do some Calculations
}
}
public void handleCollision(Ball b) {
// some more code..
ball = b;
synchronized (standBy) {
standBy.notify();
}
}
You might want to consider putting the thread to sleep and only waking it up only when your 'ball' variable becomes true. There are multiple ways of doing this, from using the very low level, wait and notify statements to using the java.util.concurrent classes which provide a less error prone way of doing this. Have a look at the documentation for the condition interface. A data structure like a BlockingQueue would also be a solution.
Yes it does. This is the most simple implementation of busy waiting, and should be avoided whenever possible. Use wait/notify or java.util.concurrent mechanisms. Maybe you should be more specific about what exactly you want to achieve to get more useful responses.
Yes, it will certainly affect performance. To increase performance, you can consider putting in a bit of a time delay (say 500ms or 1000ms or even higher) in your code depending how crucial timing is to you.
Share a BlockingQueue between your threads.
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
I found the following interesting thing. In task manager, running that infinite loop like that, would consume 17% of my CPU. Now, if I added a simple
Thread.sleep(1)
inside the loop, which is only one milisecond, the CPU use dropped to almost zero as if I was not using the program, and the response time of the program was still pretty good on average (in my case it needed to reply things fast)