patternjavaModerate
Concurrent Linked Hash Set
Viewed 0 times
hashconcurrentsetlinked
Problem
Basically I want to create a concurrent
I am mainly concerned about adding and removing iterations. Suggestions relating to implementation of set modification during iteration are also welcomed.
```
import java.util.Collection;
import java.util.LinkedHashSet;
//TODO still not sure
public class ConcurrentLinkedHashSet extends LinkedHashSet
{
private static final long serialVersionUID = 1L;
private boolean isUpdating = false;
@Override
public int size()
{
while (isUpdating)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
return (Integer) null;
}
}
return super.size();
}
@Override
public synchronized boolean addAll(Collection arg0)
{
while (isUpdating)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
return false;
}
}
isUpdating = true;
boolean result = false;
result = super.addAll(arg0);
isUpdating = false;
notify();
return result;
}
@Override
public synchronized boolean add(E arg0)
{
while (isUpdating)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
return false;
}
}
isUpdating = true;
boolean result = super.add(arg0);
isUpdating = false;
notify();
return result;
}
@Override
public boolean remove(Object arg0)
{
while (isUpdating)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
LinkedHashSet which returns proper size too.I am mainly concerned about adding and removing iterations. Suggestions relating to implementation of set modification during iteration are also welcomed.
```
import java.util.Collection;
import java.util.LinkedHashSet;
//TODO still not sure
public class ConcurrentLinkedHashSet extends LinkedHashSet
{
private static final long serialVersionUID = 1L;
private boolean isUpdating = false;
@Override
public int size()
{
while (isUpdating)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
return (Integer) null;
}
}
return super.size();
}
@Override
public synchronized boolean addAll(Collection arg0)
{
while (isUpdating)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
return false;
}
}
isUpdating = true;
boolean result = false;
result = super.addAll(arg0);
isUpdating = false;
notify();
return result;
}
@Override
public synchronized boolean add(E arg0)
{
while (isUpdating)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
return false;
}
}
isUpdating = true;
boolean result = super.add(arg0);
isUpdating = false;
notify();
return result;
}
@Override
public boolean remove(Object arg0)
{
while (isUpdating)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
Solution
There are several thread safety issues :
I'm not sure what you mean exactly by 'proper size'.
Also, I think that if you properly implement this, you'll basically end up with the same behavior as what you'd get from
- if
size(),remove()andremoveAll()need towait(), they will throw anIllegalMonitorStateExceptionsince they do not hold the lock on this at the time they callwait();
- for that same reason, they may see stale values for
isUpdating
- if
size()would be interrupted while waiting (supposing that gets fixed) its return statement would result in aNullPointerException.
- while many threads may be waiting, only one will be notified when
isUpdatingis set tofalseagain, since you callnotify()instead ofnotifyAll()
- operations such as
contains()andisEmpty()may see stale values since they are not properly synchronized.
- when interrupted all overridden methods violate the
Setcontract.
- the interrupted flag is cleared upon interruption since the InterruptedException is caught and the state is not set to interrupted again.
- not strictly a problem, but you synchronize on this. This means third party code locking on your
Setwill influence its behavior. It is preferrable to lock on a private Object.
I'm not sure what you mean exactly by 'proper size'.
Also, I think that if you properly implement this, you'll basically end up with the same behavior as what you'd get from
Collections.synchronizedSet(new LinkedHashSet())Context
StackExchange Code Review Q#61796, answer score: 10
Revisions (0)
No revisions yet.