问题
Here is the sequence that bother me begging a standard remedy for a concurrency issue
- Create a list object (lst)
- Initiate multple threads (Updater Threads)
- Send that lst to each Updater Threads to update (add) it.
- Wait for some defined time (t1) to let the Updater threads to proceed with updates.
- After t1 time expired, return lst to another application (Consumer-App) that isn't in our control.
- When return it, Updater Threads may be still updating the lst.
- Consumer-App doesn't know whether the list is still being updating in the background by the Updater Threads.
- Consumer-App do list operations (add/remove) on lst.
Problem : This will lead to concurrency issue.
How to tackle this?
How to stop updating threads after t1 effectively? Or is there any standard way to deal on this? Will the synchronizedList (Collections.synchronizedList(new ArrayList()))
help in this?
Edit : I'm aware of the CopyOnWriteArrayList also. But I'm focusing on the simple ArrayList on this
回答1:
You could use a executor service to create and terminate threads, along with a CopyOnWriteArrayList that address concurrency.
private CopyOnWriteArrayList<someObject> someArrayList = new CopyOnWriteArrayList<someObject>();
...
class NodeStatusThread implements Runnable {
private ExecutorService UpdaterThreadExecutor = null;
private int numThrd = 20; //threads
private int timeout = 10; // ten-seconds
@Override
public void run() {
for (int i=0;i<numThrd; i++ ) {
UpdaterThreadExecutor.execute(new UpdaterThread());
}
UpdaterThreadExecutor.shutdown();
try{
//Wait for thread completion
if(!UpdaterThreadExecutor.awaitTermination(timeout, TimeUnit.SECONDS)){ //return false is timeout is surpassed
UpdaterThreadExecutor.shutdownNow(); //forces thread termination
}
}catch(InterruptedException e){
UpdaterThreadExecutor.shutdownNow();
}
}
}
...
class UpdaterThread implements Runnable {
@Override
public void run() {
omeArrayList.add(someObject);
someArrayList.remove(someObject);
}
}
回答2:
4 - Wait for some defined time (t1) to let the Updater threads to proceed with updates.
This is where your design is wrong. You can never be sure every thread has finished updating the list.
You should use a sync mechanism, to allow your consumer thread wait till each one of the producers finishes.
Use CountDownLatch or CyclicBarrier.
来源:https://stackoverflow.com/questions/29375205/avoiding-a-possible-concurrency-issue-with-a-list-being-returned