I am new to Java Multithreading World, I wrote this program, I just wanted to make sure it is multithreaded program or not. In this I am creating 30 tasks that are executed by 10 threads. So this implementation is right or not? I think you can get to know what I am doing in my code. I am just generating some random ip address and passing it to method and see what’s the average time for each call after returning from the method. SO for that I wrote all the task in my run method. Any suggestions will be appreciated.
public class Testing {
public static void main(String[] args) throws InterruptedException {
int size = 10;
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(size);
// queue some tasks
for(int i = 0; i < 3 * size; i++) {
service.submit(new ThreadTask(i));
}
// wait for termination
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
class ThreadTask implements Runnable {
private int id;
public ThreadTask(int id) {
this.id = id;
}
public void run() {
System.out.println("I am task " + id);
Map<Long, Long> histgram = new HashMap<Long, Long>();
Set<String> ipNull = new HashSet<String>();
GetLocationByIpResponse resp = null;
long total = 10000;
long difference = 0;
long found = 0;
long found_country = 0;
long runs = total;
try {
long start_total = System.nanoTime();
while(runs > 0) {
String ipAddress = generateIPAddress();
long start_time = System.nanoTime();
resp = PersonalizationGeoLocationServiceClientHelper.getLocationByIp(ipAddress);
long end_time = System.nanoTime();
if(resp.getLocation() != null) {
difference = (end_time - start_time)/1000000;
} else if(resp.getLocation() == null) {
difference = 0;
}
printResult(ipAddress, resp, difference);
Long count = histgram.get(difference);
if (count != null) {
count++;
histgram.put(Long.valueOf(difference), count);
} else {
histgram.put(Long.valueOf(difference), Long.valueOf(1L));
}
runs--;
}
long end_total = System.nanoTime();
long finalTotal = (end_total - start_total)/1000000;
float avg = (float)(finalTotal) / total;
Set<Long> keys = histgram.keySet();
for (Long key : keys) {
Long value = histgram.get(key);
System.out.println("$$$GEO OPTIMIZE SVC MEASUREMENT$$$, HG data, " + key + ":" + value);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
}
}
There doesn’t seem to be anything wrong with the multi-threading as such, but there are three potential issues.
You’re measuring time elapsed. This can be unreliable at the best of times (as there are many other threads running on your computer) but if you have multiple Java threads running in parallel, it can make your measurements even less accurate.
So for this kind of task maybe a single-threaded approach works better, but don’t take my word for it: replace the random generation of IPs with a fixed list that you go through and try running the same measurements with varying numbers of threads.
I have no way to judge whether the methods that you call from
run()are themselves thread safe or not. When you write multi-threaded code, check carefully that everything you call is thread safe as well (for exampleSimpleDateFormatis not).Following on from the previous point:
System.out.println()isn’t thread safe, so you might end up with one message cutting in the middle of another. It’s not the end of the world but you probably don’t want a cluttered output.