I am getting a NullPointerException when running the code below. It appears to be in regards to synchronized(myLocks[inc]). If I am using the array object simply to guard access using each element of the array per thread, why does it need to be initialized to not null? Would I use a for loop in myChildClass? - my attempt did not succeed and I am questioning this.
class myChildCLass extends myCLass {
private Object myLocks[];
myChildClass(int inc) {
super(inc);
myLocks = new Object[inc];
}
void count(int inc) {
synchronized(myLocks[inc]){myArray[inc]++;}
}
}
Related
I am trying to implement logic that will allow me to update an array in one thread using sun's unsafe.compareAndSwapObject utility while safely iterating over that same array, in a different thread. I believe that the CopyOnWriteArrayList does what I am searching for however it uses locking for the updating and I am trying to develop a solution that does not have any locks.
The compare and swap logic is as follows:
public void add(final Object toAdd) {
Object[] currentObjects;
Object[] newObjects;
do {
currentObjects = this.objects;
newObjects = ArrayUtil.add(currentObjects, toAdd);
} while (!UNSAFE.compareAndSwapObject(this, OBJECTS_OFFSET, currentObjects, newObjects));
}
While the iteration logic is as follows (the toString() is a placeholder):
public void doWork() {
Object[] currentObjects = this.objects;
for (final Object object : currentObjects) {
object.toString();
}
}
My questions are:
Is this code safe?
Does this give me the same snapshot behaviour that CopyOnWriteArrayList does?
If it does, when is the iteration snapshot formed?
Does the fact that I'm creating a local variable have anything to do this?
If it does, how does the JVM know to not optimise this away?
Have I essentially created a variable on the stack that has a reference to the most up to date array object?
Lastly to follow up the third point above about "snapshot" creation, would the following code work the same way:
public void doWork() {
actuallyDoWork(this.objects);
}
public void actuallyDoWork() {
for (final Object object : currentObjects) {
object.toString();
}
}
Using Byte Buddy's advice API, is it possible to return from the instrumented method without actually executing it?
One use case would be to implement a cache and to return the cached value, if present, instead of computing the value again.
#Advice.OnMethodEnter
public static Object returnCachedValue(#Advice.Argument(0) String query) {
if (cache.containsKey(query)) {
// should "abort" method call
return cache.get(query);
}
}
I know that this code sample above just creates a local variable which I can get in a #Advice.OnMethodExit method. But is there a way to abort the method call on an explicit return? If yes, is this also possible for void methods?
No, this is not possible, a return value can only be set from exit advice. But it can be emulated by skipping the original method in case that a value already exists and by setting this value from the exit advice in case that the enter advice defines a value:
class MyAdvice {
#Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
public static Object returnCachedValue(#Advice.Argument(0) String query) {
if (cache.containsKey(query)) {
return cache.get(query);
} else {
return null;
}
}
#Advice.OnMethodExit
public static void processCachedValue(
#Advice.Return(readOnly = false, typing = DYNAMIC) Object returned,
#Advice.Enter Object enter) {
if (enter != null) {
returned = enter;
} else {
cache.put(query, returned);
}
}
}
Of course, this does not work if the cached value is null. To avoid this, you could wrap the value in some instance to make sure that the enter value is never null. Doing so would also allow to use the above pattern to void methods.
This might look inconvenient to program but the idea of advice is that Byte Buddy can use the advice class as a template and inline the byte code without much work to avoid a runtime overhead.
I am working with a priority queue in Java for the first time and I can't for the life of me understand what I am doing that is leading to the exception. I'm attempting to implement an ant colony type solution to the traveling salesman problem. The following is the only code being called for my AntColony class.
public AntColony(TSPInstance p) {
PriorityQueue<Ant> ants = new PriorityQueue<Ant>(new AntComparator());
size = p.getDimension();
for (int i = 0; i < size; i++) {
ants.offer(new Ant(p));
}
shortestTour = Integer.MAX_VALUE;
}
public void nextMove() {
ants.poll();
}
The code that I'm running afterwards just as a test is as follows (just in a main method).
AntColony a = new AntColony(p);
a.nextMove();
The a.nextMove() throws a NullPointerException at the ants.poll() part, but yet if I change the constructor to (for debugging purposes)
public AntColony(TSPInstance p) {
PriorityQueue<Ant> ants = new PriorityQueue<Ant>(new AntComparator());
size = p.getDimension();
for (int i = 0; i < size; i++) {
ants.offer(new Ant(p));
}
ants.poll(); //ADDED THIS
shortestTour = Integer.MAX_VALUE;
}
and then just do
AntColony a = new AntColony(p);
I don't get an exception. I'm struggling to understand how I'm getting an exception from ants.poll(), but yet when I call it from the constructor everything works. Any help with this would be appreciated. There's a lot of code for various things in this project, so I didn't think uploading it all would help anybody so let me know if there's something I should include, but I don't see how the problem could lie outside these two bits of code.
Added: Actual exception
Exception in thread "main" java.lang.NullPointerException
at data_structures.AntColony.nextMove(AntColony.java:25) (the ants.poll() part)
at algorithms.ACTest.main(ACTest.java:6) The a.nextMove() part
The ants variable in your AntColony constructor is a local variable. So when you exit the constructor, it no longer exists. Apparently the ants variable that your nextMove method is calling, is a class member.
You need to change your constructor to have:
// initialize the class member, not a local instance.
ants = new PriorityQueue<Ant>(new AntComparator());
You can just remove the PriorityQueue declaration in your AntColony constructor.
public AntColony(TSPInstance p) {
ants = new PriorityQueue<Ant>(new AntComparator());
size = p.getDimension();
...
}
UPDATE: The cause for your NullPointerException is that you are not initializing your ants property in your constructor but you are creating a new local ants instead. So the ants object in nextMove method has the same value as you provided in your class level declaration, which it's probably null.
This question already has answers here:
In java, return value within synchronized block seems like bad style. Does it really matter?
(2 answers)
Closed 5 years ago.
The code is like below
public class UAUtil {
private static String sUA = null;
private static Object sLock = new Object();
public static void clear() {
synchronized (sLock) {
sUA = null;
}
}
public static String getUserAgent() {
synchronized (sLock) {
if (sUA == null) {
Context context = CoreService.getAppContext();
sUA = ...;
}
}
return sUA;
}
So I wonder does it matter to return the sUA within or out of the synchronized block?
No one can tell you a correct answer because the code looks to be incomplete.
That said, given the code you did post why is sUA an instance variable?
Why even keep that as state. A better thing to do if you do not need that state is to return <whatever code is setting sUA>.
If there is code that you do not show that uses that state then pleas show it and ...
Also private static Object sLock = new Object(); is not a proper way to use an object reference to syncrhonize on. It must be declared final to properly guarantee semantics.
A better way would be to make sUA the lock. Instead of using null use the NullObjectPattern and have a value that represents whatever you are using null to mean.
Using a private static final AtomicReference with a value such as "" or some other null value to represent not set, you could use have something to synchronize on and hold the value at the same time. Making for more correct and cleaner code that will be easier to maintain.
So I wonder does it matter to return the sUA within or out of the
synchronized block?
no it does not matter at all, if you return outside of the synchronized block it will be absolutely fine and also if its within the synchronized block the lock will be released correctly so there is no harm.
Here is a good LINK to jon skeet's & Mark Byers answers to a similar question.
I'm trying to use observable in my code and there is this problem giving me hard time.
public class observeState extends Observable
{
public void setSelectedTransaction(int idx)
{
if (selectedTransaction != idx)
{
this.selectedTransaction = idx;
setChanged();
notifyObservers("setSelectedTransaction");
System.out.println("Observers : "+this.countObservers());
}
}
public void setLog(Log log)
{
if(theLog != log) {
theLog = log;
System.out.println(theLog.getLogTransactions().size() + "setLog");
setChanged();
notifyObservers("setLog");
System.out.println("Observers : "+this.countObservers());
}
}
There are two observers observing this observable class and it does send out notifyObservers when the setSelectedTransaction method is called with the test line "Observers : 2". However the next method setLog does not seem to have observers giving "Observers : 0". I don't think I can only use observable method once.
The mostly likely cause of this issue is that you are not calling the method on the same object. It is a common mistake to assume two objects are the same because they have the same name or some other confusion. I would print out the hashCode of each object or use a debugger to ensure you really are calling the same object.
BTW you can try making the calls in the opposite order, or more than once
to test your theory.
Either the objects that you are using to call the setSelectedTransaction and setLog are different or the observers might be removing themselves as observers in the update method.