I would like to be able to run two methods at the same time that rely on the same global variable. The first method periodically updates the shared variable, but never finishes running. The second method keeps track of time. When time runs out, the second method returns the last result of the shared variable from the first method. Below is what I have so far, with commented out pseduocode in the places where I need help.
package learning;
public class testmath{
public static void main(String[] args){
long finishBy = 10000;
int currentresult = 0;
/*
* run eversquare(0) in a seperate thread /in parallel
*/
int finalresult = manager(finishBy);
System.out.println(finalresult);
}
public static int square(int x){
return x * x;
}
public static void eversquare(int x){
int newresult;
while(2 == 2){
x += 1;
newresult = square(x);
/*
* Store newresult as a global called currentresult
*/
}
}
public static int manager(long finishBy){
while(System.currentTimeMillis() + 1000 < finishBy){
Thread.sleep(100);
}
/*
* Access global called currentresult and create a local called currentresult
*/
return currentresult;
}
}
You only need to run one additional thread:
public class Main {
/**
* Delay in milliseconds until finished.
*/
private static final long FINISH_BY = 10000;
/**
* Start with this number.
*/
private static final int START_WITH = 1;
/**
* Delay between eversquare passes in milliseconds.
*/
private static final long DELAY_BETWEEN_PASSES = 50;
/**
* Holds the current result. The "volatile" keyword tells the JVM that the
* value could be changed by another thread, so don't cache it. Marking a
* variable as volatile incurs a *serious* performance hit so don't use it
* unless really necessary.
*/
private static volatile int currentResult = 0;
public static void main(String[] args) {
// create a Thread to run "eversquare" in parallel
Thread eversquareThread = new Thread(new Runnable() {
#Override public void run() {
eversquare(START_WITH, DELAY_BETWEEN_PASSES);
}
});
// make the eversquare thread shut down when the "main" method exits
// (otherwise the program would never finish, since the "eversquare" thread
// would run forever due to its "while" loop)
eversquareThread.setDaemon(true);
// start the eversquare thread
eversquareThread.start();
// wait until the specified delay is up
long currentTime = System.currentTimeMillis();
final long stopTime = currentTime + FINISH_BY;
while (currentTime < stopTime) {
final long sleepTime = stopTime - currentTime;
try {
Thread.sleep(sleepTime);
} catch (InterruptedException ex) {
// in the unlikely event of an InterruptedException, do nothing since
// the "while" loop will continue until done anyway
}
currentTime = System.currentTimeMillis();
}
System.out.println(currentResult);
}
/**
* Increment the value and compute its square. Runs forever if left to its own
* devices.
*
* #param startValue
* The value to start with.
*
* #param delay
* If you were to try to run this without any delay between passes, it would
* max out the CPU and starve any other threads. This value is the wait time
* between passes.
*/
private static void eversquare(final int startValue, final long delay) {
int currentValue = startValue;
while (true) { // run forever (just use "true"; "2==2" looks silly)
currentResult = square(currentValue); // store in the global "currentResult"
currentValue++; // even shorter than "x += 1"
if (delay > 0) {
try { // need to handle the exception that "Thread.sleep()" can throw
Thread.sleep(delay);
} catch (InterruptedException ex) { // "Thread.sleep()" can throw this
// just print to the console in the unlikely event of an
// InterruptedException--things will continue fine
ex.printStackTrace();
}
}
}
}
private static int square(int x) {
return x * x;
}
}
I should also mention that the "volatile" keyword works for (most) primitives, since any JVM you'll see these days guarantees they will be modified atomically. This is not the case for objects, and you will need to use synchronized blocks and locks to ensure they are always "seen" in a consistent state.
Most people will also mention that you really should not use the synchronized keyword on the method itself, and instead synchronize on a specific "lock" object. And generally this lock object should not be visible outside your code. This helps prevent people from using your code incorrectly, getting themselves into trouble, and then trying to blame you. :)
Related
I want to perform a search using iterative deepening, meaning every time I do it, I go deeper and it takes longer. There is a time limit (2 seconds) to get the best result possible. From what I've researched, the best way to do this is using an ExecutorService, a Future and interrupting it when the time runs out. This is what I have at the moment:
In my main function:
ExecutorService service = Executors.newSingleThreadExecutor();
ab = new AB();
Future<Integer> f = service.submit(ab);
Integer x = 0;
try {
x = f.get(1990, TimeUnit.MILLISECONDS);
}
catch(TimeoutException e) {
System.out.println("cancelling future");
f.cancel(true);
}
catch(Exception e) {
throw new RuntimeException(e);
}
finally {
service.shutdown();
}
System.out.println(x);
And the Callable:
public class AB implements Callable<Integer> {
public AB() {}
public Integer call() throws Exception {
Integer x = 0;
int i = 0;
while (!Thread.interrupted()) {
x = doLongComputation(i);
i++;
}
return x;
}
}
I have two problems:
doLongComputation() isn't being interrupted, the program only checks if Thread.interrupted() is true after it completes the work. Do I need to put checks in doLongComputation() to see if the thread has been interrupted?
Even if I get rid of the doLongComputation(), the main method isn't receiving the value of x. How can I ensure that my program waits for the Callable to "clean up" and return the best x so far?
To answer part 1: Yes, you need to have your long task check the interrupted flag. Interruption requires the cooperation of the task being interrupted.
Also you should use Thread.currentThread().isInterrupted() unless you specifically want to clear the interrupt flag. Code that throws (or rethrows) InterruptedException uses Thread#interrupted as a convenient way to both check the flag and clear it, when you're writing a Runnable or Callable this is usually not what you want.
Now to answer part 2: Cancellation isn't what you want here.
Using cancellation to stop the computation and return an intermediate result doesn't work, once you cancel the future you can't retrieve the return value from the get method. What you could do is make each refinement of the computation its own task, so that you submit one task, get the result, then submit the next using the result as a starting point, saving the latest result as you go.
Here's an example I came up with to demonstrate this, calculating successive approximations of a square root using Newton's method. Each iteration is a separate task which gets submitted (using the previous task's approximation) when the previous task completes:
import java.util.concurrent.*;
import java.math.*;
public class IterativeCalculation {
static class SqrtResult {
public final BigDecimal value;
public final Future<SqrtResult> next;
public SqrtResult(BigDecimal value, Future<SqrtResult> next) {
this.value = value;
this.next = next;
}
}
static class SqrtIteration implements Callable<SqrtResult> {
private final BigDecimal x;
private final BigDecimal guess;
private final ExecutorService xs;
public SqrtIteration(BigDecimal x, BigDecimal guess, ExecutorService xs) {
this.x = x;
this.guess = guess;
this.xs = xs;
}
public SqrtResult call() {
BigDecimal nextGuess = guess.subtract(guess.pow(2).subtract(x).divide(new BigDecimal(2).multiply(guess), RoundingMode.HALF_EVEN));
return new SqrtResult(nextGuess, xs.submit(new SqrtIteration(x, nextGuess, xs)));
}
}
public static void main(String[] args) throws Exception {
long timeLimit = 10000L;
ExecutorService xs = Executors.newSingleThreadExecutor();
try {
long startTime = System.currentTimeMillis();
Future<SqrtResult> f = xs.submit(new SqrtIteration(new BigDecimal("612.00"), new BigDecimal("10.00"), xs));
for (int i = 0; System.currentTimeMillis() - startTime < timeLimit; i++) {
f = f.get().next;
System.out.println("iteration=" + i + ", value=" + f.get().value);
}
f.cancel(true);
} finally {
xs.shutdown();
}
}
}
I have a class that should test my Fibonacci function using multithreading
public class PerformanceTesterImpl implements PerformanceTester{
public static List<Long> executionTimesList = new ArrayList();
public static List<Runnable> tasksList = new ArrayList();
public int fib;
public PerformanceTestResult performanceTestResult;
#Override
public PerformanceTestResult runPerformanceTest(Runnable task, int calculationCount, int threadPoolSize) {
for(int i=0; i<calculationCount; i++){
tasksList.add(createTask(fib));
}
ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);
for(Runnable r : tasksList){
executor.execute(r);
}
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Here all threads should complete all work. Is it OK?
mapValues();
return performanceTestResult;
}
private PerformanceTestResult mapValues(){
Collections.sort(executionTimesList);
performanceTestResult = new PerformanceTestResult(getSum(executionTimesList), (Long)executionTimesList.get(0), (Long)executionTimesList.get(executionTimesList.size()-1));
return performanceTestResult;
}
public Runnable createTask (final int n) {
fib = n;
Runnable runnable = new Runnable() {
#Override
public void run() {
long startTime = System.currentTimeMillis();
FibCalc fibCalc = new FibCalcImpl();
fibCalc.fib(n);
long executionTime = System.currentTimeMillis() - startTime;
executionTimesList.add(executionTime);
}
};
return runnable;
}
private static long getSum(List<Long> executionTimes){
long sum = 0;
for(long l : executionTimes){
sum += l;
}
return sum;
}
}
but from time to time NULL appears in my collection and when I'm trying to sort executionTimeList I receive NullpointerException. I think there is a problem with executing threads. What should I do to correct this exception?
ArrayList is not thread safe.
From the Javadoc :
* If multiple threads access an <tt>ArrayList</tt> instance concurrently,
* and at least one of the threads modifies the list structurally, it
* <i>must</i> be synchronized externally. (A structural modification is
* any operation that adds or deletes one or more elements, or explicitly
* resizes the backing array; merely setting the value of an element is not
* a structural modification.) This is typically accomplished by
* synchronizing on some object that naturally encapsulates the list.
* If no such object exists, the list should be "wrapped" using the
* {#link Collections#synchronizedList Collections.synchronizedList}
* method. This is best done at creation time, to prevent accidental
* unsynchronized access to the list:<pre>
* List list = Collections.synchronizedList(new ArrayList(...));</pre>
When you call add from multiple threads, the ArrayList may be in inconsistent state.You should synchronize access to it.
Try :
public void run() {
long startTime = System.currentTimeMillis();
FibCalc fibCalc = new FibCalcImpl();
fibCalc.fib(n);
long executionTime = System.currentTimeMillis() - startTime;
synchronized (this) {
executionTimesList.add(executionTime);
}
}
executionTimesList is shared among all threads. They run in concurrence in your code with no synchronization. So it's logical that any inconsistency state appears if a thread works on the list and has not finished its job and the cpu gives the priority to another thread which works on the list too, the first thread will be in a inconsistent state when it will be restarted.
You must synchronize the access for the static field executionTimesList
We have a business requirement to generate random temporary passwords. As per the use case, the volume of such calls is expected to be very low (~400 calls/day). We've decided to use java.security.SecureRandom to achieve cryptographically strong randomization, as per various recommendations on the Internet, and after reading many similar posts on SO.
Now, we've written a simple randomizer (internally using the SecureRandom), which is supposed to be used as a singleton within the web application. However, we would also periodically want to reseed it, again as per recommendations on SO. To that end, below is some sample code that achieves the same. Can someone please review it and let us know if this is the right and reasonably efficient approach? Also, is there a way to avoid the synchronization in the code, while still maintaining thread safety?:
import java.security.*;
public final class Randomizer {
private static final Randomizer INSTANCE = new Randomizer();
private static final String DEFAULT_CSPRNG_ALGO = "SHA1PRNG";
private volatile SecureRandom sr;
private volatile long lastSeedTime;
public static final Randomizer getInstance() throws Exception {
return INSTANCE;
}
public int nextInt(int len) throws RuntimeException {
reseedRandomAsNeeded();
return sr.nextInt(len);
}
private Randomizer() throws RuntimeException {
try {
System.out.printf("%s Constructing Randomizer...%n", Thread.currentThread());
recreateSecureRandomInstance();
lastSeedTime = System.nanoTime();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* TODO Is there a way to avoid the synchronization overhead here? We really
* only need to synchronize when the reseed happens.
*
* #throws RuntimeException
*/
private synchronized void reseedRandomAsNeeded() throws RuntimeException {
if (isItTimeToReseed()) {
// TODO Need to do a reseed. Just get a new SecureRandom for now.
try {
recreateSecureRandomInstance();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
private boolean isItTimeToReseed() {
boolean reseed = false;
long currentTime = System.nanoTime();
long difference = ((currentTime - this.lastSeedTime) / (1000 * 1000 * 1000)/* *60 * 60 * 24*/);
// System.out.printf("%s Current time: %d, Last Reseed Time: %d, difference: %d%n",
// Thread.currentThread(), currentTime, lastSeedTime, difference);
// TODO For testing, test for just a 3 seconds difference.
if (difference > 3) {
reseed = true;
this.lastSeedTime = currentTime;
}
return reseed;
}
private void recreateSecureRandomInstance() throws NoSuchAlgorithmException {
sr = SecureRandom.getInstance(DEFAULT_CSPRNG_ALGO);
System.out.printf("%s Created a new SecureRandom instance: %s%n", Thread.currentThread(), sr);
}
}
Instead of time based, you can reseed based on number of invocations.
Maintain a counter in the class and increase it every time the random generator is called. When the counter reaches some threshold, reseed it and initialize count to to 0.
You can reseed say for every 1 million invocations.
That is the only thing I can suggest.
This question already has answers here:
What is profiling all about and how can I profile my Java program?
(4 answers)
Closed 10 years ago.
This may be a silly question for some pro java coders but I am going mad right now, so I am still asking. Please guide me in right direction someone.
How do I analyze which method/partOfMethod is consuming more time in my java program?
(I am using Eclipse and Junit)
Use jvisualvm. It is bundled in with the JDK nowadays, but a standalone version exists as well, which is more up to date.
Typically, when you start it you can pick which running java process to connect to (this may well be our running unit test). You can specify which qualified class name filters you need to track. Normally, some class instrumentation will ensue, and you will be able to track the processing time allocated to each method (cumulative time as well).
You need to get a Java profiler. Some of them integrate well in Eclipse.
Other than that, you're left with using a custom profiler class (if you don't have a lot of profiling to do and if you already suspect some bottlenecks).
Here is a simple class to do that:
/**
* Small helper class to profile the code, take timing, ...
*
* To use this, simply call the start method with an identifier. When you want to measure the time, call the stop method
* with the same identifier. To output statistics, simply call the toString method or the toCsv method to create a CSV
* file with the profiler information.
*
* #author Vincent Prat # MarvinLabs
*/
public class Profiler {
private static final int THEORETICAL_MAX_NAME_LENGTH = 50;
private static Profiler singletonInstance = null;
private Map<String, Profile> profiles; // Fast access to profiles by name
private List<Profile> profilesStack; // Profiles as created chronologically
/**
* Get access to the singleton instance (create it if necessary)
*/
public static Profiler getInstance() {
if (singletonInstance == null) {
singletonInstance = new Profiler();
}
return singletonInstance;
}
/**
* Protected constructor for singleton
*/
protected Profiler() {
profiles = new HashMap<String, Profiler.Profile>();
profilesStack = new ArrayList<Profile>();
}
/**
* Start a profile. If the profile does not exist, it will be created. If it exists, a new round of measure is
* taken.
*
* #param name
* The name of the profile. If possible, less than Profiler.THEORETICAL_MAX_NAME_LENGTH characters
*
* #see Profiler.THEORETICAL_MAX_NAME_LENGTH
*/
public void start(String name) {
Profile p = profiles.get(name);
if (p == null) {
p = new Profile(name);
profiles.put(name, p);
profilesStack.add(p);
}
p.start();
}
/**
* Stop a profile and compute some statistics about it.
*
* #param name
* The name of the profile as declared in the corresponding start method
*/
public void stop(String name) {
Profile p = profiles.get(name);
if (p == null) {
throw new RuntimeException("The profile " + name + " has not been created by a call to the start() method!");
}
p.stop();
}
/**
* Clear all the current measures. Not to be called within any start/stop pair.
*/
public void reset() {
profiles.clear();
}
/**
* Build a string containing all the information about the measures we have taken so far.
*/
#Override
public String toString() {
final StringBuffer sb = new StringBuffer();
for (Profile p : profilesStack) {
sb.append(p.toString());
sb.append("\n");
}
return sb.toString();
}
/**
* Output the measures to an output string
*/
public void toCsvFile(OutputStream os) throws IOException {
Profile.writeCsvHeader(os);
for (Profile p : profilesStack) {
p.writeCsvLine(os);
}
}
/**
* Profile information. It stores statistics per named profile.
*
* #author Vincent Prat # MarvinLabs
*/
private static class Profile {
private static final String CSV_HEADERS = "Name, Call Count, Total Time (ms), Average Time (ms), Min Time (ms), Max Time (ms), Delta Time (ms), Delta Ratio (%)\n";
private static final String FORMAT_STRING = "%-" + THEORETICAL_MAX_NAME_LENGTH + "."
+ THEORETICAL_MAX_NAME_LENGTH
+ "s: %3d calls, total %5d ms, avg %5d ms, min %5d ms, max %5d ms, delta %5d ms (%d%%)";
private static final String CSV_FORMAT_STRING = "%s,%d,%d,%d,%d,%d,%d,%d\n";
private String name;
private long startTime;
private long callCount;
private long totalTime;
private long minTime;
private long maxTime;
public Profile(String name) {
this.name = name;
this.callCount = 0;
this.totalTime = 0;
this.startTime = 0;
this.minTime = Long.MAX_VALUE;
this.maxTime = Long.MIN_VALUE;
}
public void start() {
startTime = System.currentTimeMillis();
}
public void stop() {
final long elapsed = (System.currentTimeMillis() - startTime);
if (elapsed < minTime) minTime = elapsed;
if (elapsed > maxTime) maxTime = elapsed;
totalTime += elapsed;
callCount++;
}
private String getFormattedStats(String format) {
final long avgTime = callCount == 0 ? 0 : (long) totalTime / callCount;
final long delta = maxTime - minTime;
final double deltaRatio = avgTime == 0 ? 0 : 100.0 * ((double) 0.5 * delta / (double) avgTime);
return String
.format(format, name, callCount, totalTime, avgTime, minTime, maxTime, delta, (int) deltaRatio);
}
#Override
public String toString() {
return getFormattedStats(FORMAT_STRING);
}
public static void writeCsvHeader(OutputStream os) throws IOException {
os.write(CSV_HEADERS.getBytes());
}
public void writeCsvLine(OutputStream os) throws IOException {
os.write(getFormattedStats(CSV_FORMAT_STRING).getBytes());
}
}
}
And sample usage:
Profiler.getInstance().start("marker1");
// Do something...
Profiler.getInstance().start("marker2");
// Something else...
Profiler.getInstance().stop("marker2");
// And some more...
Profiler.getInstance().stop("marker1");
// Output the profiling result
System.out.println(Profiler.getInstance().toString());
Call me old fashioned, but this is the simplest approach in my opinion:
long a, b, c, d;
a = System.currentTimeMillis();
// some code 1
b = System.currentTimeMillis();
// some code 2
c = System.currentTimeMillis();
// some code 3
d = System.currentTimeMillis();
System.out.println("Some code 1 took "+(b-a)+"mil to execute. ("+((b-a)/1000)+" seconds)");
System.out.println("Some code 2 took "+(c-b)+"mil to execute. ("+((c-b)/1000)+" seconds)");
System.out.println("Some code 3 took "+(d-c)+"mil to execute. ("+((d-c)/1000)+" seconds)");
Hope this helps :)
You could take a look at Yourkit (commercial software), which can monitor memory, CPU and many more. It has special view that show how much time was spent in methods (for example you can see that 40% of the execution time was spent in method xyz()).
The process of measuring which part of a programming takes how much runtime is called "profiling".
There are many profiling plugins for eclipse. One is described here.
there are some online tools like IdeOne which gives you the time taken for the block of code to execute. Give it a try!
A web application queries an external server. If more than 80% of the requests to the server send within the past 'n' minutes fails, then the web applicatoin should back out from querying the server and perform other logic. I could think of an atomic integer being incremented by the failed requests. But i dont think atomic integer supports any action to be executed if the value of the atomic integer reaches a particular value. Is there any smarter way to do this in java?
Well, after updating your atomic integer, you could check its value and if the 80% is met, then you could take action (like flagging that server as 'weak responding or so'). If you are working in a multi-threaded environment, there is nothing wrong with your solution.
Another solution is to have the threads call a synchronized method to increase a non-atomic integer and perform the check. That integer would have to be an attribute of the class to which this method belongs.
If you want to monitor events in the last 'N' minutes you need more than just an integer. You need to know what was happening 'N' minutes ago so you can keep your success level estimate correct.
Here is one way to do it:
import java.util.LinkedList;
/**
* Class that monitors outcomes for until the proportion of successes in a
* specified time window falls below a trigger level, at which point an action
* is invoked.
*
* #author Simon
*/
public class SuccessMonitor {
/** An outcome */
static class Outcome {
/** Time of outcome */
final long eventTime = System.currentTimeMillis();
/** True for success, false for failure */
boolean outcome;
}
/** The action to invoke when there are two few successes */
private final Runnable action_;
/** The history of outcomes in the time window */
private final LinkedList<Outcome> events_ = new LinkedList<Outcome>();
/** Number of successes in the time window */
private int goodCount_ = 0;
/** Synchronization lock */
private final Object lock_ = new Object();
/** Length of the time window in milliseconds */
private final long trackTime_;
/** The success proportion at which to invoke the action */
private final double triggerLevel_;
/**
* New monitor
*
* #param trackTime
* number of milliseconds to retain history for
* #param triggerLevel
* the level at which to invoke the action
* #param action
* the action
*/
public SuccessMonitor(long trackTime, double triggerLevel, Runnable action) {
trackTime_ = trackTime;
triggerLevel_ = triggerLevel;
action_ = action;
}
private void check(boolean result) {
// create a new outcome
Outcome out = new Outcome();
out.outcome = result;
double level;
synchronized (lock_) {
// add the new outcome
goodCount_ += (result) ? 1 : 0;
events_.addLast(out);
// remove expired outcomes
long expire = System.currentTimeMillis() - trackTime_;
while( (!events_.isEmpty())
&& (events_.getFirst().eventTime < expire) ) {
out = events_.removeFirst();
goodCount_ -= (out.outcome) ? 1 : 0;
}
// Calculate the success level.
if (events_.isEmpty()) {
// if empty assume ok
level = 1.0;
} else {
// calculate success level
level = (double) goodCount_ / events_.size();
}
}
// if level has fallen too low, invoke action
if (level < triggerLevel_) action_.run();
}
/**
* Notify this monitor of a failure.
*/
public void fail() {
check(false);
}
/**
* Reset this monitor, causing it to discard all currently stored history.
*/
public void reset() {
synchronized (lock_) {
events_.clear();
goodCount_ = 0;
}
}
/**
* Notify this monitor of a success.
*/
public void success() {
check(true);
}
}