I have client-server application in which i need to measure the rate of request arrival per second(Request rate). For this, i have a timer object that activates after every seconds, reads a synchronized counter and then sets it to zero. The counter increments on each request arrival.I used following code to detect request rate. There are so many other threads and timers in my application running.The problem is "due to the inaccuracy of timers i am not getting the perfect request rate". Is there any alternative of measuring request rate other than using timers.
public class FrequencyDetector extends TimerTask {
RequestCounter requestCounter;
FrequencyHolder frequencyHolder;
public FrequencyDetector(RequestCounter requestCounter,FrequencyHolder frequencyHolder){
this.frequencyHolder=new FrequencyHolder();
this.frequencyHolder=frequencyHolder;
}
#Override
public void run() {
int newFrequency=requestCounter.getCounter();
frequencyHolder.setFrequency(newFrequency);
requestCounter.setCounterToZero();
//calls to other fuctions
}
}
Instead of checking counter per unit time you can check time per unit counter. That will probably give you more accurate results. Algorithm is given below.
Increment counter on every request.
When counter reaches a certain FIXED_LIMIT calculate frequency by frequency=FIXED_LIMIT/duration since last record
Reset the counter and start with step 1
However this will record frequency at unpredictable intervals and if frequency of request decreases the duration between successive records will increase.
To handle it we can implement an adaptive algorithm, algorithm is given below.
Increment the counter on every request.
When counter reaches a certain ADAPTIVE_LIMIT record frequency as frequency=ADAPTIVE_LIMIT/duration since last record
Change ADAPTIVE_LIMIT as ADAPTIVE_LIMIT=frequency * DESIRED RECORD INTERVAL
Reset counter and start with step 1.
Above algorithm will reset the limit based on frequency last recorded. It's given that it will not be recording at optimal intervals but it will be pretty close.
Also it will give you highly accurate frequencies as it does not depend on any scheduled thread.
Following is an implementation of such an adaptive counter.
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
public class TestCounter {
//Keep initial counterInterval to a small value otherwise first record may take long time
final AtomicLong counterInterval = new AtomicLong(10);
AtomicLong requestCounter = new AtomicLong();
volatile long lastTime;
/**OPTIMAL_DURATION is the duration after which frequency is expected to be recorded
* Program adaptively tries to reach this duration
*/
static final double OPTIMAL_DURATION = 1.0; // 1 second
static final Random random = new Random();
public static void main(String[] args) {
System.out.println("Started ");
TestCounter main = new TestCounter();
for(int i = 0; i < 1000; i++) {
main.requestArrived();
}
}
/*
* Simulating requests
*/
public void requestArrived() {
printCounter();
try {
Thread.sleep(random.nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//This will be in some Utility class
private void printCounter() {
requestCounter.incrementAndGet();
long currentTime = System.nanoTime();
long currentInterval = counterInterval.get();
if(requestCounter.get() > currentInterval) {
if(lastTime != 0) {
long timeDelta = currentTime - lastTime;
long frequency = (long)(currentInterval / (timeDelta / 1e9));
System.out.printf("time=%.2f, frequency=%d\n", (timeDelta / 1e9), frequency);
//updating the currentInterval for the miss
long newCounterInterval = (long)(frequency * OPTIMAL_DURATION);
counterInterval.set(newCounterInterval);
}
requestCounter.set(0);
lastTime = currentTime;
}
}
}
Output
Started
time=0.54, frequency=18
time=0.98, frequency=18
time=1.01, frequency=17
time=0.96, frequency=17
time=0.99, frequency=17
time=0.85, frequency=19
time=0.96, frequency=19
time=0.82, frequency=23
time=1.08, frequency=21
time=0.98, frequency=21
time=0.94, frequency=22
time=1.06, frequency=20
time=1.07, frequency=18
time=0.99, frequency=18
time=0.98, frequency=18
time=1.02, frequency=17
time=0.92, frequency=18
time=0.92, frequency=19
time=0.89, frequency=21
time=0.82, frequency=25
time=1.31, frequency=19
time=1.02, frequency=18
Related
I'm getting periodic signals (beats per minute) from a Transmitter and now want to call methods in a fraction of the period, e.g. send 1/1, 1/2, 1/4, 1/8, 1/16,.. notes.
My solution for this is to create a thread, do a busy wait and then execute the methods. The problem here is that listening to the signal, processing it and sending it back creates a delay of a few milliseconds (depending on the system).
So now I want to determine the delay between the incoming signal and the periodic signal of the thread and if the delay is != 0, stop the current thread and start a new thread after "bpm - delay" milliseconds. How can this be done ?
Illustration:
transmitter signal: |----|----|----|----|
******runner signal : |----|----|----|----|
delay runner signal by "onePeriod - delay" milliseconds:
transmitter signal: |----|----|----|----|
***"runner signal :**** |----|----|----|----|
Both signals are now in sync.
public class Quantiser implements Receiver{
private int[] bpmsInMillis = new int[4];
private int bpmInMillis=0;
private double smallestNote = 1;
private long period=0;
private long fire=0;
private long prevTimeStamp=0;
private Runnable runny = new Runnable() {
#Override
public void run() {
while(true){
fire = System.nanoTime() + period;
while(System.nanoTime() < fire){} // busy wait
// Call some methods here.
}
}
};
private Thread thread = new Thread(runny);
#Override
public void send(MidiMessage message, long timeStamp) {
// Calculate average bpm
for(int i=0; i<bpmsInMillis.length-1;i++)
bpmsInMillis[i] = bpmsInMillis[i+1];
bpmsInMillis[bpmsInMillis.length-1] = (int) ((timeStamp - prevTimeStamp) / 1000);
bpmInMillis = arithmeticMean(bpmsInMillis);
prevTimeStamp = timeStamp;
period = (long) (bpmInMillis * smallestNote * 1000000);
if(!thread.isAlive()) {
thread.start();
}
/*
else{
Calculate delay between signal and thread-signal.
if(delay != 0){
Delay new thread by "bpm - delay" milliseconds.
Stop old thread.
Start new thread.
}
*/
}
#Override
public void close() {
}
One option would be to implment a Phase-Locked Loop (PLL).
http://en.wikipedia.org/wiki/Phase-locked_loop
Basically, you'll need two threads: One thread sits in a loop waiting for the input beats, and each time it gets a beat, it records the time of arrival.
long time_of_last_beat;
while (true) {
wait_for_next_beat();
time_of_last_beat = System.currentTimeMillis();
}
The other thread sits in a loop that goes sixteen times as fast:
long semiquaver_duration = <starting guess>;
while (true) {
notify_whoever_cares_that_its_time_for_the_next_semiquaver();
Thread.sleep(sixteenth_note_duration);
long phase_error = System.currentTimeMillis() - time_of_last_beat;
semiquaver_duration += estimate_phase_correction(phase_error);
}
I'll leave it to you to write the estimate_phase_correction() function. A linear function of the given error with the right coefficient may be all you need. If you get it right, the 16x loop should "lock in" so that every sixteenth semiquaver happens exactly on the beat.
Improvements:
have the beat loop compute the tempo.Base the starting guess for the semiquaver period on the current tempo.Notice significant (i.e. abrupt) tempo changes and re-set the semiquaver loop as needed.
In general, when I work with sound (usually sampled, not MIDI), I find it more accurate to use frame counts than elapsed time. With elapsed time there are too many unknowns (thread slicing, garbage collection, etc.). Latencies may vary, but 44100 frames (if that is the format) is always 1 sec.
With MIDI, doesn't every event have a field with the time that event is supposed to occur? I've seen readouts with both beats/measures and elapsed-time. I would use that info rather real-time time stamps when figuring any sort of positioning onto an existing Midi stream.
If this is something where the incoming is ASAP/real time, but you want to pass it through quantised, can you put scheduling info on the out-going Midi even if the incoming doesn't have it? Then you'd have a solid reference points for the positioning.
Reference on Real-Time. Low Latency Audio Processing in Java:
https://diuf.unifr.ch/main/pai/sites/diuf.unifr.ch.main.pai/files/publications/2007_Juillerat_Mueller_Schubiger-Banz_Real_Time.pdf
I've been working away at this problem for the past 10-12 hours, and was wondering if you guys could help me debug/point me in the right general direction. The object of the program is to simulate a fast food store queue-line, which I'm attempting to accomplish using:
PriorityQueue (FIFO) data structure
I've consulted with colleagues, on-campus tutoring services, professors and the given course textbook: "Java How To Program: Deitel & Deitel" to no avail.
The provided pseudocode for the problem is as follows (I'm not trying to get you to do it for me):
BigBurger Inc. wants to see if having a single person at the counter both to take orders and to serve them is feasible. At each BigBurger, customers will arrive and get in line. When they get to the head of the line they will place their order, which will be assembled and served to them. Then they will leave the BigBurger and the next person in line will be able to order.
We need to know how long a customer may be forced to wait before he or she can place an order. Given a script that lists each customer for a typical day, we want to calculate the maximum customer waiting time. Each customer in the script is characterized by an arrival time (measured in minutes after the store opened) and a service duration (the number of minutes between ordering and getting the food).
Create a class BigBurger that contains method maxWait that is given a int[] arrival and a int[] service describing all the customers and returns the maximum time spent by a customer between arriving and placing the order. Corresponding elements of arrival and service refer to the same customer, and they are given in the order in which they arrive at the store (arrival is in non-descending order).
If multiple customers arrive at the same time they will all join the line at the same time, with the ones listed earlier ahead
of ones appearing later in the list.
Definition
Class:
BigBurger
Method:
maxWait
Parameters:
int[], int[]
Returns:
int
Method signature:
int maxWait(int[] arrival, int[] service)
(be sure your method is public)
Constraints-
arrival will contain between 1 and 50 elements inclusive-
service will contain the same number of elements as arrival-
the elements of arrival will be in non-decreasing order-
each element of arrival will be between 1 and 720 inclusive-
each element of service will be between 1 and 15 inclusive
Examples
{3,3,9}
{2,15,14}
Returns: 11
Two customers arrive at time 3. The first one waits 0 time, orders, and is served after 2 minutes, leaving at time 5. The second one then orders and is served at time 20. Meanwhile a customer arrives at time 9 and waits until the second customer leaves. This last customer then orders at time 20, and is served and leaves at time 20+14 = 34. The first customer waited 0 minutes, the second waited 2 minutes (from time 3 to time 5), and the last customer waited 11 minutes (from time 9 to time 20).
I have researched for example on the net, usually arrival time is calculated using system nano time or using a random method, but here in this case the arrival time and service time is already provided in the examples and I have to calculate the total wait time of each customer. Please guide me through this as I am new to coding.
The issues I'm experiencing:
Unable to print maxWaitTime for the customer when I call return maxWaitTime in the method maxWait(int[], int[])
Here is my code:
import java.util.*;
public class QueueProgram
{
static int[] arrival = {3,3,9};
static int[] service = {2,15,14};
int waitTime;
int finishTime;
int serviceTime;
static int index;
Queue<Integer> Customers = new LinkedList<Integer>();
public int maxWait(int[] arrival, int[] service)
{
//this.arrival = arrival;
//this.service = service
int maxWaitTime = 0;
int[]finishTime = new int[arrival.length];
for(int i=0; i<arrival.length;i++)
{
int startTime;
index = i;
if(index == 0)
{
startTime = arrival[index];
System.out.println(startTime);
}
else
{
startTime = Math.max(arrival[i],finishTime[i-1]);
}
finishTime[i] = startTime + service[i];
waitTime = finishTime[i] - service[i] - arrival[i];
if(waitTime > maxWaitTime)
{
maxWaitTime = waitTime;
}
}
return maxWaitTime;
}
public static void main(String[] args)
{
QueueProgram q = new QueueProgram();
q.maxWait(arrival, service);
}
}
import java.util.*;
public class QueueProgram
{
static int[] arrival = {3,3,9};
static int[] service = {2,15,14};
int waitTime;
int finishTime;
int serviceTime;
static int index;
Queue<Integer> Customers = new LinkedList<Integer>();
public int maxWait(int[] arrival, int[] service)
{
//this.arrival = arrival;
//this.service = service
int maxWaitTime = 0;
int[]finishTime = new int[arrival.length];
for(int i=0; i<arrival.length;i++)
{
int startTime;
index = i;
if(index == 0)
{
startTime = arrival[index];
//System.out.println(startTime);
}
else
{
startTime = Math.max(arrival[i],finishTime[i-1]);
}
finishTime[i] = startTime + service[i];
waitTime = finishTime[i] - service[i] - arrival[i];
if(waitTime > maxWaitTime)
{
maxWaitTime = waitTime;
}
}
return maxWaitTime;
}
public static void main(String[] args)
{
QueueProgram q = new QueueProgram();
q.maxWait(arrival, service);
System.out.println("Maximum wait time is: " + q.maxWait(arrival, service));
}
}
variable index is redundant, i already represents array index. Secondly, waitTime can be calculated as finshTime[i-1]-arrival[i], no need to calculate startTime. Lesser operations better space and time complexity.
try this:
for(int i=0; i<arrival.length;i++)
{
if(i != 0) {
waitTime = finishTime[i-1] - arrival[i];
if(waitTime > maxWaitTime)
{ maxWaitTime = waitTime;}
}
finishTime[i] = arrival[i] + service[i];
}
I am working on a project in which I need to measure Total Time taken by program and average time taken by program. And that program is a Multithreaded program.
In that program, each thread is working in a particular range. Input parameters is Number of Threads and Number of Task.
If number of threads is 2 and number of tasks is 10 then each thread will be performing 10 tasks. So that means 2 thread will be doing 20 tasks.
So that means-
First thread should be using id between 1 and 10 and second thread should be using id between 11 and 20.
I got the above scenario working. Now I want to measure what is the total time and average time taken by all the threads. So I got the below setup in my program.
Problem Statement:-
Can anyone tell me the way I am trying to measure the Total time and Average time taken by all the threads is correct or not in my below program?
//create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(noOfThreads);
long startTime = 0L;
try {
readPropertyFiles();
startTime = System.nanoTime();
// queue some tasks
for (int i = 0, nextId = startRange; i < noOfThreads; i++, nextId += noOfTasks) {
service.submit(new XMPTask(nextId, noOfTasks, tableList));
}
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} finally {
long estimatedTime = System.nanoTime() - startTime;
logTimingInfo(estimatedTime, noOfTasks, noOfThreads);
}
private static void logTimingInfo(long elapsedTime, int noOfTasks, int noOfThreads) {
long timeInMilliseconds = elapsedTime / 1000000L;
float avg = (float) (timeInMilliseconds) / noOfTasks * noOfThreads;
LOG.info(CNAME + "::" + "Total Time taken " + timeInMilliseconds + " ms. And Total Average Time taken " + avg + " ms");
}
service.submit is getting executed only noOfThreads times. XMPTask object is created the same number of times.
The time you measure is not the consumed time but the elapsed time.
If the program tested (the JVM) is the only one on the computer, it may be relatively accurate but in a real world a lot of process runs concurrently.
I have already done this job by using a native call to the OS, on Windows (I'll complete this post Monday at my office) and Linux (/proc).
I think you would need to measure the time within the task class itself (XMPTask). Within that task you should be able to extract the id of the thread that is executing it and log that. Using this approach will require reading the logs and doing some calculations on them.
Another approach would be to keep running totals and averages as time progresses. To do this you could write a simple class that is passed into each task that has some static (per jvm) variables for tracking what each thread is doing. Then you could have a single thread outside the Threadpool that did the calculations. So if you wanted to report the average cpu time for each thread every second, this calculation thread could sleep for a second, then calculate and log all the average times, then sleep for a second....
EDIT: After re-reading the requirements, you don't need a background thread, but not sure if we are tracking the average time per thread or average time per task. I have assumed total time and average time per thread and fleshed out the idea in code below. It has not been tested or debugged but should give you a good idea of how to start:
public class Runner
{
public void startRunning()
{
// Create your thread pool
ExecutorService service = Executors.newFixedThreadPool(noOfThreads);
readPropertyFiles();
MeasureTime measure = new MeasureTime();
// queue some tasks
for (int i = 0, nextId = startRange; i < noOfThreads; i++, nextId += noOfTasks)
{
service.submit(new XMPTask(nextId, noOfTasks, tableList, measure));
}
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
measure.printTotalsAndAverages();
}
}
public class MeasureTime
{
HashMap<Long, Long> threadIdToTotalCPUTimeNanos = new HashMap<Long, Long>();
HashMap<Long, Long> threadIdToStartTimeMillis = new HashMap<Long, Long>();
HashMap<Long, Long> threadIdToStartTimeNanos = new HashMap<Long, Long>();
private void addThread(Long threadId)
{
threadIdToTotalCPUTimeNanos.put(threadId, 0L);
threadIdToStartTimeMillis.put(threadId, 0L);
}
public void startTimeCount(Long threadId)
{
synchronized (threadIdToStartTimeNanos)
{
if (!threadIdToStartTimeNanos.containsKey(threadId))
{
addThread(threadId);
}
long nanos = System.nanoTime();
threadIdToStartTimeNanos.put(threadId, nanos);
}
}
public void endTimeCount(long threadId)
{
synchronized (threadIdToStartTimeNanos)
{
long endNanos = System.nanoTime();
long startNanos = threadIdToStartTimeNanos.get(threadId);
long nanos = threadIdToTotalCPUTimeNanos.get(threadId);
nanos = nanos + (endNanos - startNanos);
threadIdToTotalCPUTimeNanos.put(threadId, nanos);
}
}
public void printTotalsAndAverages()
{
long totalForAllThreadsNanos = 0L;
int numThreads = 0;
long totalWallTimeMillis = 0;
synchronized (threadIdToStartTimeNanos)
{
numThreads = threadIdToStartTimeMillis.size();
for (Long threadId: threadIdToStartTimeNanos.keySet())
{
totalWallTimeMillis += System.currentTimeMillis() - threadIdToStartTimeMillis.get(threadId);
long totalCPUTimeNanos = threadIdToTotalCPUTimeNanos.get(threadId);
totalForAllThreadsNanos += totalCPUTimeNanos;
}
}
long totalCPUMillis = (totalForAllThreadsNanos)/1000000;
System.out.println("Total milli-seconds for all threads: " + totalCPUMillis);
double averageMillis = totalCPUMillis/numThreads;
System.out.println("Average milli-seconds for all threads: " + averageMillis);
double averageCPUUtilisation = totalCPUMillis/totalWallTimeMillis;
System.out.println("Average CPU utilisation for all threads: " + averageCPUUtilisation);
}
}
public class XMPTask implements Callable<String>
{
private final MeasureTime measure;
public XMPTask(// your parameters first
MeasureTime measure)
{
// Save your things first
this.measure = measure;
}
#Override
public String call() throws Exception
{
measure.startTimeCount(Thread.currentThread().getId());
try
{
// do whatever work here that burns some CPU.
}
finally
{
measure.endTimeCount(Thread.currentThread().getId());
}
return "Your return thing";
}
}
After writing all this, there is one thing that seems a bit strange in that the XMPTask seems to know too much about the list of tasks, when, I think you should just create an XMPTask for every task that you have, give it enough information to do the job, and submit them to the service as you create them.
I want to know if I need to measure time elapsed then Single Threaded Program is good approach or Multithreading Program is a good approach for that.
Below is my single threaded program that is measuring the time of our service-
private static void serviceCall() {
histogram = new HashMap<Long, Long>();
keys = histogram.keySet();
long total = 5;
long runs = total;
while (runs > 0) {
long start_time = System.currentTimeMillis();
result = restTemplate.getForObject("SOME URL",String.class);
long difference = (System.currentTimeMillis() - start_time);
Long count = histogram.get(difference);
if (count != null) {
count++;
histogram.put(Long.valueOf(difference), count);
} else {
histogram.put(Long.valueOf(difference), Long.valueOf(1L));
}
runs--;
}
for (Long key : keys) {
Long value = histogram.get(key);
System.out.println("MEASUREMENT " + key + ":" + value);
}
}
Output I get from this Single Threaded Program is- Total call was 5
MEASUREMENT 163:1
MEASUREMENT 42:3
MEASUREMENT 47:1
which means 1 call came back in 163 ms. 3 calls came back in 42 ms and so on.
And also I did tried using Multithreaded program as well to measure the time elapsed. Meaning hitting the service parallely with few threads and then measuring how much each thread is taking.
Below is the code for that as well-
//create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(10);
// queue some tasks
for (int i = 0; i < 1 * 5; i++) {
service.submit(new ThreadTask(i, histogram));
}
public ThreadTask(int id, HashMap<Long, Long> histogram) {
this.id = id;
this.hg = histogram;
}
#Override
public void run() {
long start_time = System.currentTimeMillis();
result = restTemplate.getForObject("", String.class);
long difference = (System.currentTimeMillis() - start_time);
Long count = hg.get(difference);
if (count != null) {
count++;
hg.put(Long.valueOf(difference), count);
} else {
hg.put(Long.valueOf(difference), Long.valueOf(1L));
}
}
And below is the result I get from the above program-
{176=1, 213=1, 182=1, 136=1, 155=1}
One call came back in 176 ms, and so on
So my question is why Multithreading program is taking a lot more time as compared to above Single threaded program? If there is some loop hole in my Multithreading program, can anyone help me to improve it?
Your multi-threaded program likely makes all the requests at the same time which puts more strain on the server which will cause it to respond slower to all request.
As an aside, the way you are doing the update isn't threadsafe, so your count will likely be off in the multithreaded scenario given enough trials.
For instance, Thread A and B both return in 100 ms at the same time. The count in histogram for 100 is 3. A gets 3. B gets 3. A updates 3 to 4. B updates 3 to 4. A puts the value 4 in the histogram. B puts the value 4 in the histogram. You've now had 2 threads believe they incremented the count but the count in the histogram only reflects being incremented once.
I have a simple recursive method, a depth first search. On each call, it checks if it's in a leaf, otherwise it expands the current node and calls itself on the children.
I'm trying to make it parallel, but I notice the following strange (for me) problem.
I measure execution time with System.currentTimeMillis().
When I break the search into a number of subsearches and add the total execution time, I get a bigger number than the sequential search. I only measure execution time, no communication or sync, etc. I would expect to get the same time when I add the times of the subtasks. This happens even if I just run one task after the other, so without threads. If I just break the search into some subtasks and run the subtasks one after the other, I get a bigger time.
If I add the number of method calls for the subtasks, I get the same number as the sequential search. So, basically, in both cases I do the same number of method calls, but I get different times.
I'm guessing there's some overhead on initial method calls or something else caused by a JVM mechanism. Any ideas what could it be?
For example, one sequential search takes around 3300 ms. If I break it into 13 tasks, it takes a total time of 3500ms.
My method looks like this:
private static final int dfs(State state) {
method_calls++;
if(state.isLeaf()){
return 1;
}
State[] children = state.expand();
int result = 0;
for (int i = 0; i < children.length; i++) {
result += dfs(children[i]);
}
return result;
}
Whenever I call it, I do it like this:
for(int i = 0; i < num_tasks; i++){
long start = System.currentTimeMillis();
dfs(tasks[i]);
totalTime += (System.currentTimeMillis() - start);
}
Problem is totalTime increases with num_tasks and I would expect to stay the same because the method_calls variable stays the same.
You should average out the numbers over longer runs. Secondly the precision of currentTimeMillis may not be sufficient, you can try using System.nanoTime().
As in all the programming languages, whenever you call a procedure or a method, you have to push the environment, initialize the new one, execute the programs instructions, return the value on the stack and finally reset the previous environment. It cost a bit! Create a thread cost also more!
I suppose that if you enlarge the researching tree you will have benefit by the parallelization.
Adding system clock time for several threads seems a weird idea. Either you are interested in the time until processing is complete, in which case adding doesn't make sense, or in cpu usage, in which case you should only count when the thread is actually scheduled to execute.
What probably happens is that at least part of the time, more threads are ready to execute than the system has cpu cores, and the scheduler puts one of your threads to sleep, which causes it to take longer to complete. It makes sense that this effect is exacerbated the more threads you use. (Even if your program uses less threads than you have cores, other programs (such as your development environment, ...) might).
If you are interested in CPU usage, you might wish to query ThreadMXBean.getCurrentThreadCpuTime
I'd expect to see Threads used. Something like this:
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Puzzle {
static volatile long totalTime = 0;
private static int method_calls = 0;
/**
* #param args
*/
public static void main(String[] args) {
final int num_tasks = 13;
final State[] tasks = new State[num_tasks];
ExecutorService threadPool = Executors.newFixedThreadPool(5);
for(int i = 0; i < num_tasks; i++){
threadPool.submit(new DfsRunner(tasks[i]));
}
try {
threadPool.shutdown();
threadPool.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println(method_calls + " Methods in " + totalTime + "msecs");
}
static final int dfs(State state) {
method_calls++;
if(state.isLeaf()){
return 1;
}
State[] children = state.expand();
int result = 0;
for (int i = 0; i < children.length; i++) {
result += dfs(children[i]);
}
return result;
}
}
With the runnable bit like this:
public class DfsRunner implements Runnable {
private State state;
public DfsRunner(State state) {
super();
this.state = state;
}
#Override
public void run() {
long start = System.currentTimeMillis();
Puzzle.dfs(state);
Puzzle.totalTime += (System.currentTimeMillis() - start);
}
}