I was recently asked a question that stumped me.
public void swapEngine(Car a, Car b) {
Engine temp = a.engine;
a.engine = b.engine;
b.engine = temp;
}
This is not a thread-safe method. If Thread 1 calls swapEngine(car1, car2) and then Thread 2 calls swapEngine(car1, car3), it is possible for car2 to end up with the engine of car3. The most obvious way to fix this problem is to synchronize the method.
Synchronizing the method introduces a potential inefficiency. What if Thread 1 calls swapEngine(car1, car2) and Thread 2 calls swapEngine(car3, car4)? In no way can these two threads interfere with each other. In this case the ideal situation would be for the two threads to swap the engines in parallel. Synchronizing the method precludes this from happening.
Is there another technique to swap these engines in a thread-safe manner while still taking advantage of parallelism?
Edit: Made method public.
As the comments say, you can lock the cars themselves. This, however could cause a deadlock if cars are not always locked in the same order.
So, if cars have a unique identifier, you can simply sort the cars, and then swap:
void swapEngine(Car a, Car b) {
Comparator<Car> byId = Comparator.comparing(Car::id);
Car[] cars = new Car[] {a, b};
Arrays.sort(cars, byId);
doSwap(cars[0]), cars[1];
}
private void doSwap(Car a, Car b) {
synchronized(a) {
synchronized(b) {
Engine temp = a.engine;
a.engine = b.engine;
b.engine = temp;
}
}
}
If the cars don't have any unique ID allowing to compare them, you can sort them by their identity hashCode (obtained using System.identityHashCode(car)). This hashCode, unless you have a huge memory, an enormous amount of cars, and bad luck, is unique. If you really fear such a situation, then Guava has an arbitrary ordering that you can use.
If you store Car.engine in AtomicReference, you could swap them using the CAS operations:
public <T> void atomicSwap(AtomicReference<T> a, AtomicReference<T> b) {
for(;;) {
T aa = a.getAndSet(null);
if (aa != null) {
T bb = b.getAndSet(null);
if (bb != null) {
// this piece will be reached ONLY if BOTH `a` and `b`
// contained non-null (and now contain null)
a.set(bb);
b.set(aa);
return;
} else {
// if `b` contained null, try to restore old value of `a`
// to avoid deadlocking
a.compareAndSet(null, aa);
}
}
}
}
Advantage of this approach is that it doesn't require right object ordering and don't use intrinsic locks. It also doesn't need to lock on full object--other properties can be manipulated in parallel.
Disadvantage is that now null values are illegal: they mean that operation on variable is in progress. You'll need to check for null when getting values and setting them anywhere but in constructor:
public <T> T getValue(AtomicReference<T> a) {
for(;;) {
T v = a.get();
if (v != null)
return v;
}
}
public <T> T setValue(AtomicReference<T> a, T value) {
for(;;) {
T old = a.get();
if (old != null && a.compareAndSet(old, value))
return old;
}
}
Related
Hello guys I have two entities connected with each other with a relationship, like this:
Entity A is known to entity B, and entity B knows entity A.
Which is the most efficient data structure that I can use in order to maintain this information?
I was think of having 2 hashmaps with key the entity's A key and value a list for each B entity that knows about A, and another one with key entity B's key etc. But I was wondering if I can use just one data structure.
I am aiming for performance in speed rather than space, so it doesn't matter if it's big as long as it's fast.
Why are you want to use a Datastructure?
It is a "normal" bidirectional association between the two objects.
class A {
B b;
....
// Perhaps you can do somthinkg like this to maintain consitsncy
void setB(B b) {
this.b = b;
b.a = a;
}
class B {
A a;
....
}
Given that you've mentioned the focus is on speed, this really comes down to how you need to acess the data, ie what question do you need to ask of the data structure.
For example, if you only need to ask the question, "does X know about Y", or "does Y know about X" then you only need one hash map. or hash set,
as long as you can produce a decent hashCode() implementation for a pair of them
(see further before for a sample hashCode implementation though probably not a good one and it's been many years since I used Java)
ie with a set
class Item extends Pair {
Item(A,B)
// override hashCode() and equals() methods as necessary
}
hashset<Item> relationships;
relationships.add(new Item(A,B))
relationships.add(new Item(B,C))
if( ! relationship.contains (new Item(B,A)))
// print "b does not know a"
or a map:
HashMap<Item,Boolean> relationships;
relationships.put(Item(A,B),True)
....
but, if you need to look at one entity and then find all the things that it knows about, then a graph structure is better.
If you're building a one time data set that doesn't need much flexibility You can implement a graph as a single linked list though, containing all edges from a starting point, and have a hash (by object key) pointing to the first edge in each list of known items.
For example, untested pseudocode, not correct java
Class Item {
Entity first
Entity second
Item next;
Item prior;
Item(x,y) { first = x; second = y; }
Item Join(nextItem) {
next = nextItem; next.prior = this; return next;
}
// override hashCode and equals() but don't use 'next' or prior as part of the hash calculation or equals comparison
//this is just for example, not sure if this is a good hash
long hashCode() { return a. hashCode() & b.hashCode(); }
}
class Graph extends HashSet<Item> {
Bool containsRelationship(Entity x, Entity y) {
return contains(new Item(x,y))
}
Bool isRcognisedEntity(Entity x) {
return contains(new Item(x,x))
}
Item getRelationships(Entity x) {
Item ret = get(new Item(x,x))
if ret is not null
return ret.next // return the first entity x knows, other than itself
else
return null // nothing known
}
Item addEntity(Entity e, Entity[] e_knows) {
Item first = new item (e,e)
add(first)
Item lastItem = first
for k in e_knows
lastItem = lastItem.join(new item(e,k))
add(lastItem)
return first
}
}
Entity a;
Entity b;
Entity c;
Graph g;
g.addEntity(a, {b,c})
g.addEntity(b, {c})
g.addEntity(c,{ a,b,c})
if g.contains(item(a,b))
Print "a knows b"
c_knows = g.getRelationships(c)
while c_knows is not null
Print "c knows " + c_knows.second
c_knows = c.next
So you see this way with just one Set, you can ask "does x know y" and also "who does x know", at the expense of some memory overhead from the next/prior attributes (you might only need one)
If instead of a common Entity base class, you have two separate classes A and B, then you could do this instead with Object, and cast the results as necessary, within routines of the Graph class to provide type safety.
For example
class Item {
Object first;
Object second;
...
}
class Graph {
// as above except use Object instead of Entity, and make the methods protected not public
}
class ABGraph extends Graph {
Iterator getRelationships(A a) {
return new B_Itemterator(super.getRelationships(a));
}
void addRelationships(A a,B[] b_knows) {
super.getRelationships( a, b_knows)
}
// Similar functions for B
}
class A_ItemIterator implements Java.collections...Iterator<A> {
A_ItemIterator(Item i) { this.i = I }
bool hasNext() { return i.next != null; }
A next() { item n = i.next; I = n; return n; }
}
// similar iterator class for B_ItemIterator
ABGraph g;
A a;
B b1;
B b2;
g.addRelationships(a, new B[]{b1,b2})
if g.contains (a,b1) // should still work
Iterator<B> i= g.getRelationships(a)
while(i.hasNext())
print " thing "+ a + " of type A knows about " + b.next() + "of type B'
I have a situation where I need to give an error message when someone tries to delete an object b from a bList and it is used in some other class say class A.
If b is not referenced in another class then I should not throw an error message.
Pseudo code for the above scenario
public class A {
B b;
void setB(B b) {
this.b = b;
}
}
public class NotifyTest {
List<B> bList = new ArrayList<>();
String notifyTest() {
A a = new A();
B b = new B();
a.setB(b);
bList.add(b);
if (b referencedSomewhere)
{
return "error";
}
else
{
bList.remove(b);
return "success";
}
}
}
Traversing my entire model to check if object b is used somewhere is a performance hit so I don't want to go for that approach.
Please let me know if there is any solution for this scenario provided by Java or suggest a better way to handle this.
Edit1 : I need an error message when b is referenced in any other place other than bList
If your intention here is to automatically free up items from the list that are no longer referenced you can use https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html
You could also use this to keep track of all keys that are not yet garbage collected. This can provide you the information about which items are already garbage collected (after becoming unreachable). However, the information won't be realtime as the garbage collector may run at arbitrary times.
I think something like the following should work for you. This is quickly put together to show you the idea. It has not been tested and will need more work if you want it to be thread safe.
class RefCounter<T>
{
private HashMap<T, Integer> counts = new HashMap<>();
public T using(T object)
{
Integer num = counts.get(object);
if (num == null)
counts.put(object, 1);
else
counts.put(object, num+1);
return object;
}
public T release(T object)
{
Integer num = counts.get(object);
if (num == null)
throw new IllegalArgumentException("Object not in RefCounter");
else if (num == 1)
counts.remove(object);
else
counts.put(object, num-1);
return object;
}
public boolean usedElsewhere(T object)
{
Integer num = counts.get(object);
return (num != null && num > 1);
}
}
When you use an object, add it to RefCounter.
refCounter.using(x);
someList.add(x);
When you are done with that object
someList.remove(index);
refCounter.release(x);
To test if the object is used elsewhere
if (refCounter.usedElsewhere(x) {
return "error";
} else {
someList.remove(index);
refCounter.release(x);
}
Remember you'll need to ensure you call using() and release() every time you keep or release an object, otherwise this is all pointless.
If the object is absolutely not used (or there's not much memory left) then java will mark it deleted, then when you start using up your memory, java will automatically do the garbage collection for you.
Most of the high level have garbage collection (GC), like java, C#, Python (iirc), etc. You only need to keep attention on memory if you use more low level languages, like C ir C++ (wich is somewhere between low and high level actually)
I have a HashMap
ConcurrentHashMap<String, Integer> count =new ConcurrentHashMap<String, Integer>();
I will use like this:
private Integer somefunction(){
Integer order;
synchronized (this) {
if (count.containsKey(key)) {
order = count.get(key);
count.put(key, order + 1);
} else {
order = 0;
count.put(key, order + 1);
}
}
return order;
}
But as you can see, this may not be ideal to handle concurrency, since only value under the same key may interfere each other.Different key does't interfere each other so it's not necessary to synchronize all operation. I want to synchronize only when the key is the same.
Can I do something that can achieve better performance on concurrency?
(I know ConcurrentHashMap and synchronize is kind of redundant here ,but let's focus on if we can only synchronize when key is same)
The whole point of ConcurrentHashMap is to facilitate concurrent operations. Here's how you can do an atomic update with no need for explicit synchronization:
private Integer somefunction() {
Integer oldOrder;
// Insert key if it isn't already present.
oldOrder = count.putIfAbsent(key, 1);
if (oldOrder == null) {
return 0;
}
// If we get here, oldOrder holds the previous value.
// Atomically update it.
while (!count.replace(key, oldOrder, oldOrder + 1)) {
oldOrder = count.get(key);
}
return oldOrder;
}
See the Javadocs for putIfAbsent() and replace() for details.
As Tagir Valeev points out in his answer, you can use merge() instead if you're on Java 8, which would shorten the code above to:
private Integer somefunction() {
return count.merge(key, 1, Integer::sum) - 1;
}
Another option would be to let the values be AtomicInteger instead. See hemant1900's answer for how to do so.
I think this might be better and simpler -
private final ConcurrentHashMap<String, AtomicInteger> count = new ConcurrentHashMap<String, AtomicInteger>();
private Integer someFunction(String key){
AtomicInteger order = count.get(key);
if (order == null) {
final AtomicInteger value = new AtomicInteger(0);
order = count.putIfAbsent(key, value);
if (order == null) {
order = value;
}
}
return order.getAndIncrement();
}
It's very easy if you can use Java-8:
return count.merge(key, 1, Integer::sum)-1;
No additional synchronization is necessary. The merge method is guaranteed to be executed atomically.
First of all, where does key even come from?
Secondly, if key will never be the same for two threads running that function at any one time you don't need to synchronize any part of the function.
If, however, two threads could have the same key at the same time then you only need:
synchronized(count) {
count.put(key, order + 1);
}
The reason for this is that only threaded mutation of an object variables will need to be synchronized. But the fact that you are using a ConcurrentHashMap should eliminate this problem (double check me on this), thus no synchronization is needed.
Here is how I do this,
private Integer somefunction(){
Integer order = count.compute(key, (String k, Integer v) -> {
if (v == null)
return 1;
else {
return v + 1;
}
});
return order-1;
}
This avoid keeps trying use replace(key,oldValue,newValue)
Will this be better for concurrency?
The problem is that a lot of environment doesn't support jdk8 yet.
Often in java I have to get a value of a property of an object which is deep in this object. For example, if I'm sure that all my sub-objects are not null, I can do that :
public function getDeepValue(A a) {
String value = a.getB().getC().getListeD().get(0).getE().getValue();
return value;
}
But in case of sub objects of the parent can be null, I have to test every object.
To do that, I see 2/3 solutions :
First, step by step :
public function getDeepValue(A a) {
if(a == null){
return null;
}
B b = a.getB();
if(b == null) {
return null;
}
C c = b.getC();
if(c == null){
return null;
}
List<D> ds = c.getListeD();
if(ds == null || ds.size() == 0){
return null;
}
D d = ds.get(0);
if(d == null) {
return null;
}
E e = d.getE()
if(e == null){
return null;
}
return e.getValue();
}
Second, test all in one if block, soooo dirty :
public function getDeepValue(A a) {
if(a != null && a.getB() != null && a.getB().getC() != null && a.getB().getC().getListeD() != null && a.getB().getC().getListeD().size() > 0 && a.getB().getC().getListeD().get(0) != null && a.getB().getC().getListeD().get(0).getE() != null){
return a.getB().getC().getListeD().get(0).getE().getValue();
}
return null;
}
Third solution, using a try catch block :
public function getDeepValue(A a) {
try {
return a.getB().getC().getListeD().get(0).getE().getValue();
} catch(NullPointerException e) {
return null;
} catch(IndexOutOfBoundsException e) {
return null;
}
}
Solution 1 seems not too bad but needs a lot of code. It is generally the solution I use.
Solution 2 is for me really dirty...
In paper, I realy like solution 3, but is it a good solution in term of performances ?
Is there any others acceptables solutions ?
Thanks for help, I hope my english is not too bad..
Regards
Solution #3 looks simple, but it can potentially hide a whole host of problems. It might be an adequate solution if you have full access to all of the classes in the chain and you know what's going on in each method and you can guarantee those methods won't cause problems with your try/catch and you're never going to change them... that's a lot of conditions to make it a worthwhile solution, but I can conceive that it's possibly a useful sufficient one.
Solution #2 looks horrid to me, especially if one or more of the get methods is a bottleneck (such as a slow database query or using a blocking network connection). The earlier in the chain such a potential bottleneck, the worse it would potentially be, as you're calling it over and over again. This of course depends on the implementation of the methods in question (even if one of them is slow, the result could be cached, for example), but you shouldn't need to know that in your client code. Even with efficient or trivial implementations, you've still got the overhead of repeated method calls you oughtn't need.
Solution #1 is the best of the three, but it's likely not the best possible. This solution takes more lines of code than the other two, but it doesn't repeat itself and it isn't going to be tripped up by the implementations of the other methods. (Note: If you do not have access to the classes in the chain for refactoring, I would use this solution.)
A better solution than #1 would be to refactor the classes so that the client code doesn't need to know about this chain at all. Something along these lines:
class Client {
public Mumble getDeepValue(A a) { return a == null ? null : a.getDeepValue(); }
}
class A {
private B b;
public Mumble getDeepValue() { return b == null ? null : b.getDeepValue(); }
}
class B {
private C c;
public Mumble getDeepValue() { return c == null ? null : c.getDeepValue(); }
}
class C {
private List<D> ds;
public Mumble getDeepValue() {
D d = ds == null || ds.size() == 0 ? null : ds.get(0);
return d == null ? null : d.getDeepValue();
}
}
class D {
private E e;
public Mumble getDeepValue() { return e == null ? null : e.getMumble(); }
}
class E {
private Mumble m;
public Mumble getMumble() { return m; }
}
As you can see, the longest chain any of these classes has is to access the public members of an element of a collection that is a private member of the class. (Essentially ds.get(0).getDeepValue()) The client code doesn't know how deep the rabbit hole goes, only that A exposes a method which returns a Mumble. Client doesn't even need to know that the classes B, C, D, E, or List exist anywhere!
Additionally, if I were designing this system from the ground up, I would take a good long look at whether it could be restructured such that the actual Mumble object wasn't so deep. If I could reasonably get away with storing the Mumble within A or B, I'd recommend doing it. Depending on the application, that may not be possible however.
in terms of performance solution 3 is the best one. In addition It is neat and easy to understand , For example looking at a loop example:
int[] b = somevalue;
for(int i=0;i<b.length;i++){
//do something
}
in this case for every iteration we execute the condition. However, there is another approach for it which uses try and catch
int[] b = somevalue;
try{
for(int i=0;;i++){
//do something
}
}catch(IndexOutOfBoundException e){
// do something
}
on the second solution,the loop keeps going until we reach the end of the loop which then it throws IndexOutOfBoundException as soon as we reach the end of the array. meaning we don't check for the condition no more. thus faster.
Say I have objects A,B,C,D. They can contain references to one another, for example, A might reference B and C, and C might reference A. I want to create segments but dont want to create them twice, so I don't want segment A C and segment C A, just 1 of them. So I want to keep a list of created segments, ex: A C, and check if I already have an A C or C A and skip it if so.
Is there a data structure that can do this?
Thanks
if(list.contains(a,b)
{
//dont add
}
you may introduce something like
class PairKey<T extends Comparable<T>> {
final T fst, snd;
public PairKey(T a, T b) {
if (a.compareTo(b) <=0 ) {
fst = a;
snd = b;
} else {
fst = b;
snd = a;
}
}
#Override
public int hashCode() {
return a.hashCode() & 37 & b.hashCode();
}
#Override
public boolean equals(Object other) {
if (other == this) return true;
if (!(other instanceOf PairKey)) return false;
PairKey<T> obj = (PairKey<T>) other;
return (obj.fst.equals(fst) && obj.snd.equals(snd));
}
}
then you may put edges into HashSet < PairKey < ? extends Comparable> > and then check if the given pair is already there.
You will need to make your vertexes comparable, so it will be possible to treat PairKey(A,B) equal to PairKey(B,A)
And then HashSet will do the rest for you, e.g you will be able to query
pairs.contains(new PairKey(A,B));
and if pairs contain either PairKey(A,B) or PairKey(B,A) - it will return true.
hashCode implementation might be slightly different, may be IDE will generate something more sophisticated.
Hope that helps.
I would use an object called Pair that would look something like this:
class Pair
{
Node start;
Node end;
public Pair(Node start, Node end)
{
this.start=start;
this.end=end;
}
public Pair reverse()
{
return new Pair(end,start);
}
}
Now you can do something like this:
if(pairs.contains(currentPair) || pairs.contains(currentPair.reverse())
{
continue;
} else{
pairs.add(currentPair);
}
As pointed out in the comments, you will need to implement equals and hashcode. However, doing the check in equals to make it match the reversal of the segment is a bad practice in a pure OO since. By implementing equals in the fashion, described within the comments, would bind Pair to your application only and remove the portability of it.
You can use a set of sets of objects.
Set<Set<MyObjectType>> segments = new HashSet<Set<MyObjectType>>();
Then you can add two-element sets representing pairs of MyObject. Since sets are unordered, if segments contains a set with A and B, attempting to add a set containing B and A will treat it as already present in segments.
Set<MyObjectType> segment = new HashSet<MyObjectType>();
segment.add(A); // A and B are instances of MyObjectType
segment.add(B);
segments.add(segment);
segment = new HashSet<MyObjectType>();
segment.add(B);
segment.add(A);
segments.add(segment);
System.out.println("Number of segments: " + segments.size()); // prints 1
Your problem is related with graph theory.
What you can try is to remove that internal list and create a Incidence Martrix, that all you objects share.
The final solution mostly depend of the task goal and available structure. So is hard to choose best solution for you problem with the description you have provided.
Use java.util.Set/ java.util.HashSet and keep adding the references you find e.g.
Set set1 = new HashSet();
set1.add(A), set1.Add(C), set1.Add(C)
You can add this finding in an external set, as finalSet.add(set1)
Set<Set> finalSet = new HashSet<Set>();
finalSet.add(set1);
This will filter out the duplicates automatically and in the end, you will be left with A & C only.