List, Set and Map are not thread-safety by nature. Java 1.5 offers APIs to make it synchronized.
Collections.synchronizedList(new ArrayList());
Collections.synchronizedSet(new Hashset());
Collections.synchronizedMap(new HashMap());
The add/remove methods will become thread-safe by doing as above. One new real problem is "fail-fast". When a thread is iterating over this collections and another thread does add/remove into the same collection, then java.util.ConcurrentModificationException will be thrown.
The above said theory is explained in N number of java papers. But, I'm depicting the fail-fast scenario with an example program. This program is as simple as for self-explanatory.
The below code contains a list and methods to iterate over the list, add elements into it and remove elements from it. Thread t1, t2 and t3 are started together to produce the fail-fast scenario.
Collections.synchronizedList(new ArrayList());
Collections.synchronizedSet(new Hashset());
Collections.synchronizedMap(new HashMap());
The add/remove methods will become thread-safe by doing as above. One new real problem is "fail-fast". When a thread is iterating over this collections and another thread does add/remove into the same collection, then java.util.ConcurrentModificationException will be thrown.
The above said theory is explained in N number of java papers. But, I'm depicting the fail-fast scenario with an example program. This program is as simple as for self-explanatory.
The below code contains a list and methods to iterate over the list, add elements into it and remove elements from it. Thread t1, t2 and t3 are started together to produce the fail-fast scenario.
package samples.concurrency;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class Sample15_1
{
private List<String> l = Collections.synchronizedList(new ArrayList<String>());
private final static int iterationCount = 9000;
Sample15_1()
{
for (int i = 0; i < iterationCount; i++)
{
l.add(new String("A" + i));
}
}
public void addName(String str)
{
l.add(str);
}
public void removeName(String str)
{
l.remove(str);
}
public void printNames() throws Exception
{
int count = 0;
Iterator<String> i = l.iterator();
while (i.hasNext())
{
count++;
if (count % 40 == 0)
System.out.println();
System.out.print(i.next()+" ");
}
}
public static void main(String[] args) throws Exception
{
final Sample15_1 sample = new Sample15_1();
Thread t1 = new Thread()
{
public void run()
{
try
{
sample.printNames();
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
Thread t2 = new Thread()
{
public void run()
{
for (int i = 0; i < iterationCount; i++)
sample.addName("B" + i);
}
};
Thread t3 = new Thread()
{
public void run()
{
for (int i = 0; i < iterationCount; i++)
sample.removeName("A" + i);
}
};
t3.start();
t2.start();
t1.start();
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class Sample15_1
{
private List<String> l = Collections.synchronizedList(new ArrayList<String>());
private final static int iterationCount = 9000;
Sample15_1()
{
for (int i = 0; i < iterationCount; i++)
{
l.add(new String("A" + i));
}
}
public void addName(String str)
{
l.add(str);
}
public void removeName(String str)
{
l.remove(str);
}
public void printNames() throws Exception
{
int count = 0;
Iterator<String> i = l.iterator();
while (i.hasNext())
{
count++;
if (count % 40 == 0)
System.out.println();
System.out.print(i.next()+" ");
}
}
public static void main(String[] args) throws Exception
{
final Sample15_1 sample = new Sample15_1();
Thread t1 = new Thread()
{
public void run()
{
try
{
sample.printNames();
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
Thread t2 = new Thread()
{
public void run()
{
for (int i = 0; i < iterationCount; i++)
sample.addName("B" + i);
}
};
Thread t3 = new Thread()
{
public void run()
{
for (int i = 0; i < iterationCount; i++)
sample.removeName("A" + i);
}
};
t3.start();
t2.start();
t1.start();
}
}
No comments:
Post a Comment