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.
When these two threads execute the run method, they create their own copy of the local count variable inside their own private stack. As these stacks are private two threads cannot share the same copy of the count variable.
Two variables can be swapped in one line in Java. This is done by using the given statement. x = x ^ y ^ (y = x); where x and y are the 2 variables.
By running instances or programs concurrently we ensure high throughput and higher performance as we can utilize the untapped resources like operating system hardware etc. For example, if a system has several CPUs, then the application can utilize these CPUs effectively and increase the throughput.
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 love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With