I am using the following code to produce a unique sequence of id numbers in a concurrent system:
String idNodePath = "/somenode/idNode";
Stat stat = null;
Integer id = null;
try{
stat = zk.setData(idNodePath, new byte[0], -1);
id = stat.getVersion();
} catch ( KeeperException e){
zk.create(idNodePath, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.getData(idNodePath, false, stat);
}
I am concerned that this may not be correct way to achieve this using Zookeeper, although I did find someone else using a similar approach here: http://permalink.gmane.org/gmane.comp.java.hadoop.zookeeper.user/3216 which give me a small amount of reassurance.
My question is: is this a safe thing to do in a concurrent system? Is there a guarantee that id numbers will be unique and sequential? (i.e. no gaps when all id numbers are put together from all concurrent processes/machines)
Update: Fix NullPointerException bug in code pointed out by AlexR (thanks!)
Your code definitely contains bug. Take a look on stat variable. It is null before try block and initialized there. But if KeeperException is thrown you arrive to the next line
int id = stat.getVersion();
that throws NullPointerException because stat is still null.
Now concerning the concurrency. As fat as I understand zk is a member of your class. In this case the code is incorrect too. Think about 2 threads. First evaluates line stat = zk.setData(), i.e. changes the state of zk. Second arrives to the same line and evaluates it too, i.e. changes the state of shared object zk according to its parameters. Then first thread calls zk.getVersion(), i.e. gets version according to the state that was set by thread 2.
I cannot give you any recommendations about changing your code because I do not know what would you like to achieve. If you can explain your task in details you will probably get better recommendation how to implement it.
Related
Basically what I am asking is if It's possible to use the same variable in an if statement. Assigning it a new value halfway through the statement so that I don't have to initialize a new variable. I know this is probably horrible practice but I'm just curious if it can be done.
Here is the closest I feel that I have gotten so far:
if(curID + 1 != (curID = myScanner.nextInt())) {
System.out.print(j++);
break;
} else {
j++;
}
Sorry if this is a duplicate but I couldn't seem to find anything on it. More than likely because I forgot the technical terms.
Edit: Forgot to say that when I ran it I think it just used the new variable for both instances because the loop just broke. I could be wrong though.
There is no benefit to writing
if(curID++ != (curID = myScanner.nextInt())) {
versus
if(curID != (curID = myScanner.nextInt())) {
because the value stored back by ++ will be lost by the subsequent assignment. That you're thinking of doing this suggests you're fuzzy on what these things mean.
EDITED: per discussion in comments, you're also confused about the difference between prefix and postfix forms of ++. The postfix form evaluates to the value before the increment occurs.
But in any case, the whole thing is better written without the embedded assignment.
int prevId = curId;
curId = myScanner.nextInt();
if (prevId + 1 != curId) {
...
}
EDITED: added the + 1 to make the code work as discussed in the comments, as distinct from as originally written.
Your concern that you "don't have to initialize a new variable" is misplaced. Adding prevId costs almost nothing.
Writing it per my suggestion means you don't have to wonder about what Java may or may not do (though you can readily determine it from the online Java Language Specification), since it is now obvious. And that's the most important thing in programming.
I am using phonetic matching for different words in Java. i used Soundex but its too crude. i switched to Metaphone and realized it was better. However, when i rigorously tested it. i found weird behaviour. i was to ask whether thats the way metaphone works or am i using it in wrong way. In following example its works fine:-
Metaphone meta = new Metaphone();
if (meta.isMetaphoneEqual("cricket","criket")) System.out.prinlnt("Match 1");
if (meta.isMetaphoneEqual("cricket","criketgame")) System.out.prinlnt("Match 2");
This would Print
Match 1
Mathc 2
Now "cricket" does sound like "criket" but how come "cricket" and "criketgame" are the same. If some one would explain this. it would be of great help.
Your usage is slightly incorrect. A quick investigation of the encoded strings and default maximum code length shows that it is 4, which truncates the end of the longer "criketgame":
System.out.println(meta.getMaxCodeLen());
System.out.println(meta.encode("cricket"));
System.out.println(meta.encode("criket"));
System.out.println(meta.encode("criketgame"));
Output (note "criketgame" is truncated from "KRKTKM" to "KRKT", which matches "cricket"):
4
KRKT
KRKT
KRKT
Solution: Set the maximum code length to something appropriate for your application and the expected input. For example:
meta.setMaxCodeLen(8);
System.out.println(meta.encode("cricket"));
System.out.println(meta.encode("criket"));
System.out.println(meta.encode("criketgame"));
Now outputs:
KRKT
KRKT
KRKTKM
And now your original test gives the expected results:
Metaphone meta = new Metaphone();
meta.setMaxCodeLen(8);
System.out.println(meta.isMetaphoneEqual("cricket","criket"));
System.out.println(meta.isMetaphoneEqual("cricket","criketgame"));
Printing:
true
false
As an aside, you may also want to experiment with DoubleMetaphone, which is an improved version of the algorithm.
By the way, note the caveat from the documentation regarding thread-safety:
The instance field maxCodeLen is mutable but is not volatile, and accesses are not synchronized. If an instance of the class is shared between threads, the caller needs to ensure that suitable synchronization is used to ensure safe publication of the value between threads, and must not invoke setMaxCodeLen(int) after initial setup.
I am working on some inherited code and I am not use to the entity frame work. I'm trying to figure out why a previous programmer coded things the way they did, sometimes mixing and matching different ways of querying data.
Deal d = _em.find(Deal.class, dealid);
List<DealOptions> dos = d.getDealOptions();
for(DealOptions o : dos) {
if(o.price == "100") {
//found the 1 item i wanted
}
}
And then sometimes i see this:
Query q = _em.createQuery("select count(o.id) from DealOptions o where o.price = 100 and o.deal.dealid = :dealid");
//set parameters, get results then check result and do whatver
I understand what both pieces of code do, and I understand that given a large dataset, the second way is more efficient. However, given only a few records, is there any reason not to do a query vs just letting the entity do the join and looping over your recordset?
Some reasons never to use the first approach regardless of the number of records:
It is more verbose
The intention is less clear, since there is more clutter
The performance is worse, probably starting to degrade with the very first entities
The performance of the first approach will degrade much more with each added entity than with the second approach
It is unexpected - most experienced developers would not do it - so it needs more cognitive effort for other developers to understand. They would assume you were doing it for a compelling reason and would look for that reason without finding one.
can anyone tell me how to read multiple lines and store their value.
eg:file.txt
Probable Cause: The network operator has issued an alter attribute command for
the specified LCONF assign. The old value and the new value are show
Action Taken : The assign value is changed from the old value to the new
value. Receipt of this message does not guarantee that the new attribute
value was accepted by clients who use it. Additional messages may be.
Probable Cause: The network operator has issued an info attribute command for
the specified LCONF assign. The default value being used is displaye
Action Taken : None. Informational use only.
In the above file, Probable Cause and Action Taken are the column of a database table. And after Probable Cause: those are the value to be stored in the database table for probable cause column, same goes with action taken.
So how can i read the multiple lines and store their value? I have to read the value for probable cause until the line comes with Action Taken. I'm using BufferedReader and the readLine() method to read one line at a time. So can anyone tell me how to read directly from probable cause to action taken no matter how many line comes between them.
The simplest way is probably to just keep a List<String> for each value, with loops something like this:
private static final String ACTION_TAKEN_PREFIX = "Action Taken ";
...
String line;
while ((line = reader.readLine()) != null)
{
if (line.startsWith(ACTION_TAKEN_PREFIX))
{
actions.add(line.substring(ACTION_TAKEN_PREFIX))
// Keep reading the rest of the actions
break;
}
causes.add(line);
}
// Now handle the fact that either we've reached the end of the file, or we're
// reading the actions
Once you've got a "Probable Cause" / "Actions Taken" pair, convert the list of strings back to a single string, e.g. joining with "\n", and then insert in the database. (The Joiner class in Guava will make this easier.)
The tricky bit is dealing with anomalies:
What happens if you don't start with a Probable Cause?
What happens if one probable cause is followed by another, or one set of actions is followed by another?
What happens if you reach the end of the file after reading a probably cause but no list of actions?
I don't have the time to write out a complete solution now, but hopefully the above will help to get you going.
I've been reading about non-blocking approaches for some time. Here is a piece of code for so called lock-free counter.
public class CasCounter {
private SimulatedCAS value;
public int getValue() {
return value.get();
}
public int increment() {
int v;
do {
v = value.get();
}
while (v != value.compareAndSwap(v, v + 1));
return v + 1;
}
}
I was just wondering about this loop:
do {
v = value.get();
}
while (v != value.compareAndSwap(v, v + 1));
People say:
So it tries again, and again, until all other threads trying to change the value have done so. This is lock free as no lock is used, but not blocking free as it may have to try again (which is rare) more than once (very rare).
My question is:
How can they be so sure about that? As for me I can't see any reason why this loop can't be infinite, unless JVM has some special mechanisms to solve this.
The loop can be infinite (since it can generate starvation for your thread), but the likelihood for that happening is very small. In order for you to get starvation you need some other thread succeeding in changing the value that you want to update between your read and your store and for that to happen repeatedly.
It would be possible to write code to trigger starvation but for real programs it would be unlikely to happen.
The compare and swap is usually used when you don't think you will have write conflicts very often. Say there is a 50% chance of "miss" when you update, then there is a 25% chance that you will miss in two loops and less than 0.1% chance that no update would succeed in 10 loops. For real world examples, a 50% miss rate is very high (basically not doing anything than updating), and as the miss rate is reduces, to say 1% then the risk of not succeeding in two tries is only 0.01% and in 3 tries 0.0001%.
The usage is similar to the following problem
Set a variable a to 0 and have two threads updating it with a = a+1 a million times each concurrently. At the end a could have any answer between 1000000 (every other update was lost due to overwrite) and 2000000 (no update was overwritten).
The closer to 2000000 you get the more likely the CAS usage is to work since that mean that quite often the CAS would see the expected value and be able to set with the new value.
Edit: I think I have a satisfactory answer now. The bit that confused me was the 'v != compareAndSwap'. In the actual code, CAS returns true if the value is equal to the compared expression. Thus, even if the first thread is interrupted between get and CAS, the second thread will succeed the swap and exit the method, so the first thread will be able to do the CAS.
Of course, it is possible that if two threads call this method an infinite number of times, one of them will not get the chance to run the CAS at all, especially if it has a lower priority, but this is one of the risks of unfair locking (the probability is very low however). As I've said, a queue mechanism would be able to solve this problem.
Sorry for the initial wrong assumptions.