I have the following code, which checks for the number of rows in the database.
private void checkMMSRows(){
Cursor curPdu = getContentResolver().query(Uri.parse("content://mms/part"), null, null, null, null);
if (curPdu.moveToNext()){
int number = curPdu.getCount();
System.out.println(number);
}
}
I will to run this code every second and do something when the value has changed. The problems is, how do I go about "detecting" the change? Any help would be appreciated.
Very basically, add a class variable - you can either make it static across all instances of the class, or an instance variable (by removing the static keyword).
Each time you get a number, you can compare it to oldNumber. After the comparison, set the oldNumber to the current number - so you have something to compare against next time:
private static int oldNumber = -1;
private void checkMMSRows(){
Cursor curPdu = getContentResolver().query(Uri.parse("content://mms/part"), null, null, null, null);
if (curPdu.moveToNext()){
int number = curPdu.getCount();
System.out.println(number);
if(number != oldNumber){
System.out.println("Changed");
// add any code here that you want to react to the change
}
oldNumber = number;
}
}
Update:
My answer's a straight code hack & slash solution, but I'd probably recommend amit's answer.
Depends on the context in which this is run.
Assuming that the Object which this method belongs to will live between different checks, all you need to do is to add a int currentValue field to the object, store the value in there first time you check, and then compare the value with the stored ones in subsequent checks (and update if necessary)
int currentValue = 0;
private void checkMMSRows(){
Cursor curPdu = getContentResolver().query(Uri.parse("content://mms/part"), null, null, null, null);
if (curPdu.moveToNext()){
int newValue = curPdu.getCount();
if (newvalue != currentValue) {
//detected a change
currentValue = newValue;
}
System.out.println(newValue);
}
}
Instead of checking every second if your element was changed, you might want to consider an alternative: allow only special access to this element, and do something once it is changed.
This this is a well known design pattern and is called the Observer Pattern.
This is a well-proven design pattern, which will make your code more readable, and will probably also enhance performance, and correctness of your application.
EDIT:
In java, you can use the Observer interface and Observable class in order to do so.
you can regsister a braodcastreceiver for new coming mms and this way you will come to know that the change has taken place..
Related
I saw a lot of SO posts saying that Java set any uninitialized variable to null (like here, here or here...).
But lately, I went upon this code, written by Google here :
cur = cr.query(builder.build(), INSTANCE_PROJECTION, selection, selectionArgs, null);
while (cur.moveToNext()) {
String title = null;
long eventID = 0;
long beginVal = 0;
// Get the field values
eventID = cur.getLong(PROJECTION_ID_INDEX);
beginVal = cur.getLong(PROJECTION_BEGIN_INDEX);
title = cur.getString(PROJECTION_TITLE_INDEX);
// Do something with the values.
...
}
I would genuinely rather do this :
// Get the field values
long eventID = cur.getLong(PROJECTION_ID_INDEX);
long beginVal = cur.getLong(PROJECTION_BEGIN_INDEX);
String title = cur.getString(PROJECTION_TITLE_INDEX);
I assume Google developpers are somehow really qualified, so I wonder, since we are in the very same scope : what are the pros and cons of declaring the first way instead of the second ?
It's a question of style. I don't initialise unnecessarily for two reasons:
Doing so clobbers an extra check a Java compiler will give you as compilation will not be successful if a variable that is not initialised on all control paths is encountered.
It gives the impression that null is an acceptable value for the reference, which often it isn't.
I’m getting PMD red colored violation
Avoid reassigning parameters such as 'bankRequest'
This is my method
#Override
public BankDTO loadTariff(BankDTO bankRequest, int[] executionLevels) {
double[] fee = null;
for (int level : executionLevels) {
// Check the tariff availability from execution level one to .....
fee = loadCokaAndBankFee(bankRequest,level);
if (fee != null) { // if fee found reload the bank request with new
// amount
bankRequest = reloadBankRequest(bankRequest, fee);
break; // no need to go for any other level deep level cover //
// here.
} // if tariff not found use the esb provided amounts
}
return bankRequest;
}
Could someone explain what wrong with this code. If I ignore it what is the impact.
In your case, there's a parameter named bankRequest. Inside the method, you are assigning bankRequest a value.
By some, it is considered an ill approach to assign values to parameters within a method's body, as it is, at times, confusing. Some developers prefer always assuming that a parameter is never assigned any value during a method's run.
To avoid that, you can declare an alternative variable of type BankDTO:
BankDTO updatedRequest = bankRequest;
...
...
updatedRequest = reloadBankRequest(bankRequest, fee);
...
...
return updatedRequest;
You should avoid re assigning variables for the reasons already given. Anyway,instead of assigning a new variable consider just returning from the loop when finding the correct value. Thiswould also make "break" redundant.
In java parameters are called by reference. In your case this means, if you change the object bankRequest it is not visible outside of the method loadTariff.
After the line bankRequest = reloadBankRequest(bankRequest, fee); the variable bankRequest points to a different object of BankDTO.
If you want to change internal values of bankRequest and use it after calling loadTariff you should do something like bankRequest.loadRokaAndBankFee(fee).
Reassigning values to incoming parameters is not recommended. Use temporary local variables instead.
Example(s):
public class Foo {
private void foo(String bar) {
bar = "something else";
}
}
reference: http://pmd.sourceforge.net/pmd-5.0.1/rules/java/design.html
Reassigning values to the incoming parameters is not recommended. Use temporary local variable.
public BankDTO loadTariff(BankDTO bankRequest, int[] executionLevels) {
double[] fee = null;
BankDTO updatedBankRequest = bankRequest;
for (int level : executionLevels) {
fee = loadCokaAndBankFee(bankRequest,level);
if (fee != null) {
updatedBankRequest = reloadBankRequest(bankRequest, fee);
break;
} }
return updatedBankRequest;
}
I am working on a project to create a simple auction server that multiple clients connect to. The server class implements Runnable and so creates a new thread for each client that connects.
I am trying to have the current highest bid stored in a variable that can be seen by each client. I found answers saying to use AtomicInteger, but when I used it with methods such as atomicVariable.intValue() I got null pointer exception errors.
What ways can I manipulate the AtomicInteger without getting this error or is there an other way to have a shared variable that is relatively simple?
Any help would be appreciated, thanks.
Update
I have the AtomicInteger working. The problem is now that only the most recent client to connect to the server seems to be able to interact with it. The other client just sort of freeze.
Would I be correct in saying this is a problem with locking?
Well, most likely you forgot to initialize it:
private final AtomicInteger highestBid = new AtomicInteger();
However working with highestBid requires a great deal of knowledge to get it right without any locking. For example if you want to update it with new highest bid:
public boolean saveIfHighest(int bid) {
int currentBid = highestBid.get();
while (currentBid < bid) {
if (highestBid.compareAndSet(currentBid, bid)) {
return true;
}
currentBid = highestBid.get();
}
return false;
}
or in a more compact way:
for(int currentBid = highestBid.get(); currentBid < bid; currentBid = highestBid.get()) {
if (highestBid.compareAndSet(currentBid, bid)) {
return true;
}
}
return false;
You might wonder, why is it so hard? Image two threads (requests) biding at the same time. Current highest bid is 10. One is biding 11, another 12. Both threads compare current highestBid and realize they are bigger. Now the second thread happens to be first and update it to 12. Unfortunately the first request now steps in and revert it to 11 (because it already checked the condition).
This is a typical race condition that you can avoid either by explicit synchronization or by using atomic variables with implicit compare-and-set low-level support.
Seeing the complexity introduced by much more performant lock-free atomic integer you might want to restore to classic synchronization:
public synchronized boolean saveIfHighest(int bid) {
if (highestBid < bid) {
highestBid = bid;
return true;
} else {
return false;
}
}
I wouldn't look at the problem like that. I would simply store all the bids in a ConcurrentSkipListSet, which is a thread-safe SortedSet. With the correct implementation of compareTo(), which determines the ordering, the first element of the Set will automatically be the highest bid.
Here's some sample code:
public class Bid implements Comparable<Bid> {
String user;
int amountInCents;
Date created;
#Override
public int compareTo(Bid o) {
if (amountInCents == o.amountInCents) {
return created.compareTo(created); // earlier bids sort first
}
return o.amountInCents - amountInCents; // larger bids sort first
}
}
public class Auction {
private SortedSet<Bid> bids = new ConcurrentSkipListSet<Bid>();
public Bid getHighestBid() {
return bids.isEmpty() ? null : bids.first();
}
public void addBid(Bid bid) {
bids.add(bid);
}
}
Doing this has the following advantages:
Automatically provides a bidding history
Allows a simple way to save any other bid info you need
You could also consider this method:
/**
* #param bid
* #return true if the bid was successful
*/
public boolean makeBid(Bid bid) {
if (bids.isEmpty()) {
bids.add(bid);
return true;
}
if (bid.compareTo(bids.first()) <= 0) {
return false;
}
bids.add(bid);
return true;
}
Using an AtomicInteger is fine, provided you initialise it as Tomasz has suggested.
What you might like to think about, however, is whether all you will literally ever need to store is just the highest bid as an integer. Will you never need to store associated information, such as the bidding time, user ID of the bidder etc? Because if at a later stage you do, you'll have to start undoing your AtomicInteger code and replacing it.
I would be tempted from the outset to set things up to store arbitrary information associated with the bid. For example, you can define a "Bid" class with the relevant field(s). Then on each bid, use an AtomicReference to store an instance of "Bid" with the relevant information. To be thread-safe, make all the fields on your Bid class final.
You could also consider using an explicit Lock (e.g. see the ReentrantLock class) to control access to the highest bid. As Tomasz mentions, even with an AtomicInteger (or AtomicReference: the logic is essentially the same) you need to be a little careful about how you access it. The atomic classes are really designed for cases where they are very frequently accessed (as in thousands of times per second, not every few minutes as on a typical auction site). They won't really give you any performance benefit here, and an explicit Lock object might be more intuitive to program with.
This is a small part of my code. My project is to simulate a whole school system. To add teachers, courses etc. All of my class members are private, so i created setters and getters methods. I try to give to 'teachersNum' a value and this must be automatic(not from keyboard). So i want to give it value 1 if its the first teacher etc. I hope you can understand. Sorry for my English.
public void addTeachersList(Teachers teachers) {
if(this.teachersSize<100){
this.teachersList[this.teachersSize] = teachers;
this.teachersList[this.teachersSize].getTeacherNum() = this.teachersSize -1;
this.teachersSize++;
}
}
You'll have to call a setter:
this.teachersList[this.teachersSize].setTeacherNum(this.teachersSize-1);
Calling the getter getTeacherNum just gives you the number, it isn't a reference to that property.
Although I must say, you'd really do yourself a favor by using a List implementation instead of arrays.
In this line
this.teachersList[this.teachersSize].getTeacherNum() = this.teachersSize -1;
getTeacherNum() returns a value. You can't assign to it.
You have the problem here
this.teachersList[this.teachersSize].getTeacherNum() = this.teachersSize -1;
.getTeacherNum() will return a value which must be stored in a variable on left side.
eg:
temp = .getTeacherNum();
And its better to use a static variable to keep the count of teachers, so every time a teacher is created he/she gets a nos which is different from the previous one
eg:
xxxx001
xxxx002
xxxx003
You have the problem here
this.teachersList[this.teachersSize].getTeacherNum() = this.teachersSize -1;
.getTeacherNum() will return a value which must be stored in a variable on left side.
eg: temp = .getTeacherNum();
And its better to use a static variable to keep the count of teachers, so every time a teacher is created he/she gets a nos which is different from the previous one
eg:
xxxx001
xxxx002
xxxx003
I'd like to be able to conditionally replace a value in a ConcurrentHashMap. That is, given:
public class PriceTick {
final String instrumentId;
...
final long timestamp;
...
And a class (let's call it TickHolder) which owns a ConcurrentHashMap (let's just call it map).
I wish to be able to implement a conditional put method, so that if there's no entry for the key, the new one is inserted, but if there is an existing entry, the new one is inserted only if the timestamp value in the new PriceTick is greater than the existing one.
For an old-school HashMap solution, TickHolder would have a put method:
public void add(PriceTick tick) {
synchronized(map) {
if ((map.get(tick.instrumentId) == null)
|| (tick.getTimestamp() > map.get(tick.instrumentId).getTimestamp()) )
map.put(tick.instrumentId, tick);
}
}
With a ConcurrentHashMap, one would want to drop the synchronization and use some atomic method like replace, but that's unconditional. So clearly the "conditional replace" method must be written.
However, since the test-and-replace operation is non-atomic, in order to be thread safe, it would have to be synchronized - but my initial reading of the ConcurrentHashMap source leads me to think that external synchronization and their internal locks will not work very well, so at a very minimum, every Map method which performs structural changes and the containing class performs would have to be synchronized by the containing class... and even then, I'm going to be fairly uneasy.
I thought about subclassing ConcurrentHashMap, but that seems to be impossible. It makes use of an inner final class HashEntry with default access, so although ConcurrentHashMap is not final, it's not extensible.
Which seems to mean that I have to fall back to implementing TickHolder as containing an old-school HashMap in order to write my conditional replace method.
So, the questions: am I right about the above? Have I (hopefully) missed something, whether obvious or subtle, which would lead to a different conclusion? I'd really like to be able to make use of that lovely striped locking mechanism here.
The non-deterministic solution is to loop replace():
do {
PriceTick oldTick = map.get(newTick.getInstrumentId());
} while ((oldTick == null || oldTick.before(newTick)) && !map.replace(newTick.getInstrumentId(), oldTick, newTick);
Odd though it may seem, that is a commonly suggested pattern for this kind of thing.
#cletus solution formed the base for my solution to an almost identical problem. I think a couple of changes are needed though as if oldTick is null then replace throws a NullPointerException as stated by #hotzen
PriceTick oldTick;
do {
oldTick = map.putIfAbsent(newTick.getInstrumentId());
} while (oldTick != null && oldTick.before(newTick) && !map.replace(newTick.getInstrumentId(), oldTick, newTick);
The correct answer should be
PriceTick oldTick;
do {
oldTick = map.putIfAbsent(newTick.getInstrumentId(), newTick);
if (oldTick == null) {
break;
}
} while (oldTick.before(newTick) && !map.replace(newTick.getInstrumentId(), oldTick, newTick);
As an alternative, could you create a TickHolder class, and use that as the value in your map? It makes the map slightly more cumbersome to use (getting a value is now map.getValue(key).getTick()), but it lets you keep the ConcurrentHashMap's behavior.
public class TickHolder {
public PriceTick getTick() { /* returns current value */
public synchronized PriceTick replaceIfNewer (PriceTick pCandidate) { /* does your check */ }
}
And your put method becomes something like:
public void updateTick (PriceTick pTick) {
TickHolder value = map.getValue(pTick.getInstrumentId());
if (value != null) {
TickHolder newTick = new TickHolder(pTick);
value = map.putIfAbsent(pTick.getInstrumentId(), newTick);
if (value == null) {
value = newTick;
}
}
value.replaceIfNewer(pTick);
}