Android Sync Blocks

I have one function: fillFromDB , which populates ArrayList instances called list from SQLite DB.

I also have another Thread that should clear this list and refill it.

I am having some problems with this list, because sometimes another Thread clears the list while the first one still fills it, raising an IndexOutOfBoundsException on the adapter.

 // This occurs onCreate() fillFromDb(list); downloadAndRepopulateList(list); private void downloadAndRepopulateList(List list) { new Thread(new Runnable() { @Override public void run() { list.clear(); // Some other clode } } } 

I know that the problem is that they are not thread safe, but I have never used synchronized before.

So my question is:

if I changed the download function as follows:

 private void downloadAndRepopulateList(List list) { new Thread(new Runnable() { @Override public void run() { synchronized(list) { list.clear(); // Some other clode } } } } 

will it wait until UIThread completes filling the list with fillFromDb() and then continues to clear and re-fill it?

If not, how do I do this?

+4
source share
2 answers

Although I would prefer to use LinkedBlockingQueue . i.e.

  list = new LinkedBlockingQueue<SomeType>(); fillFromDb(list); downloadAndRepopulateList(list); private void downloadAndRepopulateList(List list) { new Thread(new Runnable() { @Override public void run() { list.clear(); // Some other clode } } } 

LinkedBlockingQueue itself will manage the synchronization for you, and you do not need to keep the lock, etc.

If you want to do this with an Arraylist , you will need to make it atomic on both sides. that is, to access list , they must first hold the lock on the object and continue. If someone holds the lock, then wait.

 synchonized(list){ fillFromDb(list); downloadAndRepopulateList(list); } private void downloadAndRepopulateList(List list) { new Thread(new Runnable() { @Override public void run() { synhronized(list){ list.clear(); } // Some other clode } } } 
+5
source

To do this, you must also synchronize your fillFromDb method. Thus, in the end, you will have two synchronized parts, one of which synchronizes your list filling, and the other synchronizes with the list. You can also use your list as a mutex, but I would recommend that you have a separate object as a mutex, it could just like Object mutex = new Object(); .

+1
source

Source: https://habr.com/ru/post/1492764/


All Articles