|
Synchronized Collections
in Java |
|
Prof. David Bernstein |
| Computer Science Department |
| bernstdh@jmu.edu |
Dispatcher is used by
a DailyDispatchHandler and
a RealTimeDispatchHandler, each of which
executes in its own threadDispatcher had synchronized
dispatch() and makeVehicleAvailable()
methodsDispatcher uses a synchronized
List
import java.util.*;
/**
* Used to dispatch vehicles in a fleet (e.g., emergency
* response vehicles).
*
* This version uses a synchronized LinkedList.
*
* @author Prof. David Bernstein, James Madison University
* @version 5.0b
*/
public class Dispatcher
{
protected int numberOfVehicles;
protected List<Integer> availableVehicles;
/**
* Construct a new Dispatcher
*
* @param n The number of vehicles in the fleet
*/
public Dispatcher(int n)
{
int i;
numberOfVehicles = n;
availableVehicles = Collections.synchronizedList(new LinkedList<Integer>());
for (i=0; i < n; i++)
{
makeVehicleAvailable(i);
}
}
/**
* Dispatch an available vehicle
*
* @param task The task to be handled
* @return true if a vehicle was dispatched
*/
public boolean dispatch(String task)
{
boolean ok;
int vehicle;
Integer v;
try
{
v = availableVehicles.remove(0);
vehicle = v.intValue();
sendMessage(vehicle, task);
ok = true;
}
catch (IndexOutOfBoundsException ioobe)
{
ok = false;
}
return ok;
}
/**
* Makes a vehicle available for future dispatching
*
* @param vehicle The number of the vehicle
*/
public void makeVehicleAvailable(int vehicle)
{
availableVehicles.add(new Integer(vehicle));
}
/**
* Sends a message to a vehicle
*
* @param vehicle The number of the vehicle
* @param message The message to send
*/
private void sendMessage(int vehicle, String message)
{
// This method would normally transmit the message
// to the vehicle. For simplicity, it now writes it
// to the screen instead.
System.out.println(vehicle+"\t"+message+"\n");
System.out.flush();
}
}
List list = Collections.synchronizedList(new ArrayList<String>());
String element;
if (list.size() > 0)
{
element = list.remove(0);
}
Map map = Collections.synchronizedMap(new HashMap<String, Account>());
if (!map.containsKey(key))
{
map.put(key, value);
}
List list = Collections.synchronizedList(new ArrayList<String>());
String element;
synchronized(list)
{
if (list.size() > 0)
{
element = list.remove(0);
}
}
Map map = Collections.synchronizedMap(new HashMap<String, Account>());
synchronized(map)
{
if (!map.containsKey(key))
{
map.put(key, value);
}
}
Collection is changed
while using an Iterator
(or a for-each loop)?Iterator object's
hasNext() or next() method
will throw a ConcurrentModificationException
Iterator objects are said to
fail-fast
List list = Collections.synchronizedList(new ArrayList<String>());
Iterator<String> i = list.iterator();
while (i.hasNext()) // Might throw ConcurrentModificationException
{
element = i.next(i); // Might throw ConcurrentModificationException
}
List list = Collections.synchronizedList(new ArrayList<String>());
for (int i=0; i<list.size(); i++)
{
// list might be changed in another thread
element = list.get(i);
}
toArray() and iterate over the array