I am new to Java and trying to understand concurrency in Java. While exploring I came across this code on quite a popular page on Java concurrency:
public class CrawledSites {
private List<String> crawledSites = new ArrayList<String>();
private List<String> linkedSites = new ArrayList<String>();
public void add(String site) {
synchronized (this) {
if (!crawledSites.contains(site)) {
linkedSites.add(site);
}
}
}
/**
* Get next site to crawl. Can return null (if nothing to crawl)
*/
public String next() {
if (linkedSites.size() == 0) {
return null;
}
synchronized (this) {
// Need to check again if size has changed
if (linkedSites.size() > 0) {
String s = linkedSites.get(0);
linkedSites.remove(0);
crawledSites.add(s);
return s;
}
return null;
}
}
}
I believe that function next() here is violating mutual exclusion, as below lines:
if (linkedSites.size() == 0) {
return null;
}
are kept outside synchronized block so in case some thread is modifying linkedSites inside synchronized blocks in add() or next(), other threads are allowed to read it.
Please correct me in case I am wrong.