Create ten instances of a class simultaneously using threads - java

I am trying to understand threads in Java. As an exercise, I created an Ice Cream class as follows.
public class ThreadIceCream {
private String flavor = "";
private String[] specialFlavors = { "Vanilla", "Chocolate", "Butter Pecan", "Strawberry", "Chocolate Chip", "Cherry", "Coffee" };
// Constructor for ThreadIceCream class
public ThreadIceCream() {
int randInt = (int) (Math.random() * specialFlavors.length);
flavor = specialFlavors[randInt];
System.out.println("Enjoy your " + flavor + " IceCream!");
} }
The ThreadIceCream class is a simple class that creates an IceCream object with a random flavor every time the class is initialized. Here is the TestStub I am using.
public class TestStub {
public static void main(String[] args) {
ThreadIceCream Th1 = new ThreadIceCream();
ThreadIceCream Th2 = new ThreadIceCream();
} }
Now I want to create 10 Icecreams (i.e. Create 10 instances of the ThreadIceCream class simultaneously) and I want to use threads in Java to do this. I tried a few things but they were no were close.

Well it's not really that hard:
Thread[] threads = new Thread[10];
for(int i = 0; i < 10; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
ThreadIceCream tic = new ThreadIceCream();
}
});
threads[i].start();
}
for(int i = 0; i < 10; i++) {
threads[i].join();
}
Sure, this won't do much because the work performed by each thread is so small that the overhead to start the threads is actually higher, but whatever.
You should also learn to use the ExecutorService for higher efficiency. Pure threads are heavyweight and are rarely a good solution for anything, especially in groups. Here's an ExecutorService version of the above:
ExecutorService exec = Executors.newFixedThreadPool(10);
for(int i = 0; i < 10; i++) {
exec.submit(new Runnable() {
public void run() {
ThreadIceCream tic = new ThreadIceCream();
}
});
}
exec.shutdown();
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
Here we are creating a pool of 10 threads and submitting 10 tasks. The threads are recycled betweeen task executions, so only 10 threads are ever created, no matter how many tasks you submit. Since the tasks are so small several tasks may even be executed on the same thread, but that's actually a good thing.

Related

Synchronized keyword Java speed effienciency

Feel free to correct me if I am wrong!
The synchronized keyword in java makes a method unable to be run be different threads simultaneously. In my program I have 4 different threads that run on the same time counting to 100.000.
When adding the synchronized keyword to the method being performed, it should take four times the amount of time as it would multithreading?
Executing the programs either way, takes roughly 16 seconds.
Heres my code!
public class ExerciseThree {
public static void main(String[] args) {
Even even = new Even();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
System.out.println(even.next());
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
System.out.println(even.next());
}
});
Thread t3 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
System.out.println(even.next());
}
});
Thread t4 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
System.out.println(even.next());
}
});
System.out.println("starting thread 1");
t1.start();
System.out.println("starting thread 2");
t2.start();
System.out.println("starting thread 3");
t3.start();
System.out.println("starting thread 4");
t4.start();
}
}
The method being called by the threads
public class Even {
private int n = 0;
// public synchronized int next() {
public int next() {
n++;
n++;
return n;
}
}
As already pointed out in the comment section, microbenchmarking is a complex matter as many factors influence the execution time (e.g., just-in-time compilation and garbage collection). A good reference was already provided in the comments section, but I suggest that you also take a look at my answer for a similar question which links to an external resource by Peter Sestoft that provides a very good introduction to microbenchmarking and what one needs to be aware of.
It has already been mentioned that println() has no place in a microbenchmark like this. In addition, I'd like to point out that you should use some sort of synchronization mechanism (e.g., a CountDownLatch) to make sure that the four threads start performing their work at the same time. The overhead involved in creating and starting the threads may result in the earlier threads getting a headstart on their work during the time it takes for the later ones to start, thereby creating less contention for the even lock than what you expect. This could for example look something like this:
public class ExerciseThree {
public static void main(String[] args) {
final CountDownLatch startSignal = new CountDownLatch(1);
final CountDownLatch threadReadyCheck = new CountDownLatch(4);
final CountDownLatch threadDoneCheck = new CountDownLatch(4);
Even even = new Even();
Thread t1 = new Thread(() -> {
threadReadyCheck.countDown();
startSignal.await();
for (int i = 0; i < 100000; i++) {
even.next();
}
threadDoneCheck.countDown();
});
Thread t2 = new Thread(() -> {
threadReadyCheck.countDown();
startSignal.await();
for (int i = 0; i < 100000; i++) {
even.next();
}
threadDoneCheck.countDown();
});
Thread t3 = new Thread(() -> {
threadReadyCheck.countDown();
startSignal.await();
for (int i = 0; i < 100000; i++) {
even.next();
}
threadDoneCheck.countDown();
});
Thread t4 = new Thread(() -> {
threadReadyCheck.countDown();
startSignal.await();
for (int i = 0; i < 100000; i++) {
even.next();
}
threadDoneCheck.countDown();
});
t1.start();
t2.start();
t3.start();
t4.start();
// Wait until all threads are ready to perform their work.
threadReadyCheck.await();
// All threads ready.
// This is where you log start time.
long start = System.nanoTime();
// Let threads progress to perform their actual work.
startSignal.countDown();
// Wait for threads to finish their work.
threadDoneCheck.await();
long end = System.nanoTime();
// Note that this is again subject to many factors, for example when the main thread gets scheduled again after the workers terminate.
long executionTime = end - start;
}
}
With println being much more expensive than the computation, it's all about concurrent execution of it. However, println itself is synchronized, so there can be no speed up.
Without it, doing just
public int next() {
n++;
n++;
return n;
}
is subject to many optimizations. Especially the double increment can be replaced by n+=2 and the return gets eliminated as the returned value doesn't get used. A loop like
for (int i = 0; i < 100000; i++) {
even.next());
}
can be reduced to just n += 200000.
Benchnmarking is hard in general and especially in Java. By all means, use JMH, which takes care of most problems.

java multithreading make universal code using list with different size against number of cores

We want to process List exList (which has a variable size) in parallel.
How could we make this to work with different sizes of exList and minimum one core and max 4 cores ?
The given code assumes that exList.size > 40. (if size is < 40 se simply use one thread).
But all of that is hard coded. So - how can this code be enhanced to make parallel runs "dynamically"; dependent on the size of our list?
int threads = Runtime.getRuntime().availableProcessors();
final int start = exList.size() / threads;
try {
Thread t1 = new Thread(new Runnable() {
public void run()
{
for(int i =0; i < start;i++){
System.out.println(exList.get(i));
}
}});
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run()
{
for(int i =start; i < start * 2;i++){
System.out.println(exList.get(i));
}
}});
t2.start();
Thread t3 = new Thread(new Runnable() {
public void run()
{
for(int i = start *2; i < start * 3;i++){
System.out.println(exList.get(i));
}
}});
t3.start();
Thread t4 = new Thread(new Runnable() {
public void run()
{
for(int i =start * 3 ; i < exList.size();i++){
System.out.println(exList.get(i));
}
}});
t4.start();
}catch (Exception e){
}
You are already computing the number of threads that might be good to use.
int threads = Runtime.getRuntime().availableProcessors();
But you are simply drawing the wrong conclusion from that! The idea of computing that start value only adds confusion; it doesn't give you anything meaningful. Instead, simply go for:
int listSize = exList.size();
for (int shardNumber = 0; shardNumber < threads; shardNumber++) {
new Thread(new Runnable() {
public void run() {
for(int listIndex = shardNumber*listSize; listIndex < (shardNumber+1)*listSize; listIndex++) {
System.out.println(exList.get(listIndex));
}
}}).start();
}
In other words: you simply slice your exList into thread "shards". And then you create one thread to process such a shard/slice.
Please note: the above isn't tested. It is meant as idea to get you going! You want to carefully check my math to ensure that the inner loop is really fetching the correct elements!
And hint: avoid creating threads and starting threads on that low level. You better create an ExecutorService and submit runnables. Use abstractions, not "low level" stuff.
exList is a list of strings
final int threads = Runtime.getRuntime().availableProcessors();
final int listSize = exList.size()/threads + 1;
Thread[] t = new Thread[threads];
for (int i = 0; i < threads; i++) {
final int finalshardNumber = i;
final int finalI = i;
t[i] = new Thread() {
public void run() {
for(int listIndex = finalshardNumber * listSize; listIndex < ( finalshardNumber + 1) *listSize; listIndex++) {
try {
//thread // index of exList //string from exList
System.out.println( finalI +" "+ listIndex +" "+ exList.get(listIndex));
}catch (Exception e){
}
}
}}; t[i].start();
}

Synchronized java code performs times faster than unsynchronized one

I work on a high concurrency app. In the app code I try to avoid synchronization where possible. Recently, when comparing test performance of a unsynchronized and synchronized code versions, it turned out synchronized code performed three-four times faster than its unsynchronized counterpart.
After some experiments I came to this test code:
private static final Random RND = new Random();
private static final int NUM_OF_THREADS = 3;
private static final int NUM_OF_ITR = 3;
private static final int MONKEY_WORKLOAD = 50000;
static final AtomicInteger lock = new AtomicInteger();
private static void syncLockTest(boolean sync) {
System.out.println("syncLockTest, sync=" + sync);
final AtomicLong jobsDone = new AtomicLong();
final AtomicBoolean stop = new AtomicBoolean();
for (int i = 0; i < NUM_OF_THREADS; i++) {
Runnable runner;
if (sync) {
runner = new Runnable() {
#Override
public void run() {
while (!stop.get()){
jobsDone.incrementAndGet();
synchronized (lock) {
monkeyJob();
}
Thread.yield();
}
}
};
} else {
runner = new Runnable() {
#Override
public void run() {
while (!stop.get()){
jobsDone.incrementAndGet();
monkeyJob();
Thread.yield();
}
}
};
}
new Thread(runner).start();
}
long printTime = System.currentTimeMillis();
for (int i = 0; i < NUM_OF_ITR;) {
long now = System.currentTimeMillis();
if (now - printTime > 10 * 1000) {
printTime = now;
System.out.println("Jobs done\t" + jobsDone);
jobsDone.set(0);
i++;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stop.set(true);
}
private static double[] monkeyJob() {
double[] res = new double[MONKEY_WORKLOAD];
for (int i = 0; i < res.length; i++) {
res[i] = RND.nextDouble();
res[i] = 1./(1. + res[i]);
}
return res;
}
I played with the number of threads, workload, test iterations - each time synchronized code perfomed much faster than unsunchronized one.
Here are results for two different values of NUM_OF_THREADS
Number of threads:3 syncLockTest, sync=true Jobs
done 5951 Jobs done 5958 Jobs done 5878 syncLockTest,
sync=false Jobs done 1399 Jobs done 1397 Jobs
done 1391
Number of threads:5 syncLockTest, sync=true Jobs
done 5895 Jobs done 6464 Jobs done 5886 syncLockTest,
sync=false Jobs done 1179 Jobs done 1260 Jobs
done 1226
Test environment
Windows 7 Professional
Java Version 7.0
Here's a simillar case Synchronized code performs faster than unsynchronized one
Any ideas?
Random is a thread-safe class. you are most likely avoiding contention on calls into the Random class by synchronizing around the main job.
This is fascinating. I think #jtahlborn nailed it. If I move the Random and make it local to the thread, the times for the non-sync jump ~10x while the synchronized ones don't change:
Here are my times with a static Random RND:
syncLockTest, sync=true
Jobs done 8800
Jobs done 8839
Jobs done 8896
syncLockTest, sync=false
Jobs done 1401
Jobs done 1381
Jobs done 1423
Here are my times with a Random rnd local variable per thread:
syncLockTest, sync=true
Jobs done 8846
Jobs done 8861
Jobs done 8866
syncLockTest, sync=false
Jobs done 25956 << much faster
Jobs done 26065 << much faster
Jobs done 26021 << much faster
I also wondered if this was GC related but moving the double[] res to being a thread local did not help the speeds at all. Here's the code I used:
...
#Override
public void run() {
// made this be a thread local but it affected the times only slightly
double[] res = new double[MONKEY_WORKLOAD];
// turned rnd into a local variable instead of static
Random rnd = new Random();
while (!stop.get()) {
jobsDone.incrementAndGet();
if (sync) {
synchronized (lock) {
monkeyJob(res, rnd);
}
} else {
monkeyJob(res, rnd);
}
}
}
...
private static double[] monkeyJob(double[] res, Random rnd) {
for (int i = 0; i < res.length; i++) {
res[i] = rnd.nextDouble();
res[i] = 1. / (1. + res[i]);
}
return res;
}

how do I set up the following thread in Java?

I have a thread with the following form:
each execution of each thread is supposed to run a function in the class. That function is completely safe to run by itself. The function returns a value, say an int.
After all threads have been executed, the function values need to be accumulated.
So, it goes (in pseudo-code) something like that:
a = 0
for each i between 1 to N
spawn a thread independently and call the command v = f(i)
when thread finishes, do safely: a = a + v
end
I am not sure how to use Java in that case.
The problem is not creating the thread, I know this can be done using
new Thread() {
public void run() {
...
}
}
the problem is accumulating all the answers.
Thanks for any info.
I would probably do something like:
public class Main {
int a = 0;
int[] values;
int[] results;
public Main() {
// Init values array
results = new int[N];
}
public int doStuff() {
LinkedList<Thread> threads = new LinkedList<Thread>();
for (final int i : values) {
Thread t = new Thread() {
public void run() {
accumulate(foo(i));
}
};
threads.add(t);
t.start();
}
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) {
// Act accordingly, maybe ignore?
}
}
return a;
}
synchronized void accumulate(int v) {
// Synchronized because a += v is actually
// tmp = a + v;
// a = tmp;
// which can cause a race condition AFAIK
a += v;
}
}
Use an ExecutorCompletionService, Executor, and Callable.:
Start with a Callable that calls your int function:
public class MyCallable implements Callable<Integer> {
private final int i;
public MyCallable(int i) {
this.i = i;
}
public Integer call() {
return Integer.valueOf(myFunction(i));
}
}
Create an Executor:
private final Executor executor = Executors.newFixedThreadPool(10);
10 is the maximum number of threads to execute at once.
Then wrap it in an ExecutorCompletionService and submit your jobs:
CompletionService<Integer> compService = new ExecutionCompletionService<Integer>(executor);
// Make sure to track the number of jobs you submit
int jobCount;
for (int i = 0; i < n; i++) {
compService.submit(new MyCallable(i));
jobCount++;
}
// Get the results
int a = 0;
for (int i = 0; i < jobCount; i++) {
a += compService.take().get().intValue();
}
ExecutorCompletionService allows you to pull tasks off of a queue as they complete. This is a little different from joining threads. Although the overall outcome is the same, if you want to update a UI as the threads complete, you won't know what order the threads are going to complete using a join. That last for loop could be like this:
for (int i = 0; i < jobCount; i++) {
a += compService.take().get().intValue();
updateUi(a);
}
And this will update the UI as tasks complete. Using a Thread.join won't necessarily do this since you'll be getting the results in the order that you call the joins, not the order that the threads complete.
Through the use of the executor, this will also allow you to limit the number of simultaneous jobs you're running at a given time so you don't accidentally thread-bomb your system.

Java - multiple Runnables per Thread

I got a fixed number of threads. I want each thread to run three Runnables, one after another. Here's some pseudocode to explain:
Thread[] threads = new Thread[4];
for (int i = 0; i < threads.length; i++) {
// Set the first tasks.
threads[i] = new Thread(new FirstRunnable());
threads[i].start();
}
for (int i = 0; i < threads.length; i++)
threads[i].join(); // wait until the first tasks are done
for (int i = 0; i < threads.length; i++) {
// Set the second task.
threads[i].setRunnable(new SecondRunnable());
threads[i].start();
}
for (int i = 0; i < threads.length; i++)
threads[i].join(); // wait until the second tasks are done
...
Using a ThreadPool sounds way overkill, especially since I'm headed for performance, performance, performance. What's the best way to implement this in Java?
Whenever you see new Thread(...).start(), make use of the Executors framework. In particular, make use of Executors.newFixedThreadPool(...).
Seems like a good use for a newFixedThreadPool from the Executors class.
So your code would look something like:
ExecutorService es = Executors.newFixedThreadPool(4);
List<Future> futures = new ArrayList<Future>();
for (int x = 0; x < 4; x ++) {
futures.add(es.submit(new FirstRunnable()));
}
while (futures.size() > 0) {
futures.remove(0).get();
}
for (int x = 0; x < 4; x ++) {
futures.add(es.submit(new SecondRunnable()));
}
while (futures.size() > 0) {
futures.remove(0).get();
}
Of course, you could probably easily refactor the code above to remove code duplication.
You can use a CyclicBarrier and a "CombinedRunnable" as shown below. The barrier allows the threads to all wait for each other to finish, before proceeding to the next runnable.
CyclicBarrier barrier = new CyclicBarrier(4);
Runnable r = new CombinedRunnable(barrier, new FirstRunnable(), new SecondRunnable());
Thread[] threads = new Thread[4];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(r);
threads[i].start();
}
The CombinedRunnable class:
public class CombinedRunnable implements Runnable{
private final CyclicBarrier barrier;
private final Runnable[] runnables;
public CombinedRunnable(CyclicBarrier barrier, Runnable... runnables){
this.barrier = barrier;
this.runnables = runnables;
}
/* (non-Javadoc)
* #see java.lang.Runnable#run()
*/
#Override
public void run() {
for(Runnable r: runnables){
r.run();
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
An idiomatic way to achieve this is by using an Executor in conjunction with a CompletionService. This allows you to map many units of work to a fixed size pool of threads and also provides an elegant mechanism for blocking until all work is complete.
Note that your concern about how using a thread pool might impact efficiency is not really an issue: The main overhead is in creating individual threads, which you were doing anyway; the additional object creation overhead in creating a pool will be negligible.
// Create fixed thread pool and wrap in a CompletionService to allow for easy access to completed tasks.
// We don't have an explicit result for each Runnable so parameterise the service on Void.
CompletionService<Void> cs = new ExecutorCompletionService<Void>(Executors.newFixedThreadPool(3));
// Create units of work for submission to completion service.
Runnable[] runnables = ...
// Submit runnables. Note that we don't care about the result so pass in null.
for (Runnable r : runnables) {
cs.submit(r, null);
}
// Take each *completed* result in turn, blocking until a completed result becomes available.
for (int i=0; i<runnables.length; ++i) {
Future<Void> completed = cs.take();
}
Executor Framework is just for you.
Here's the pseudocode:
1. Create executor service
Executors type1Runnables = Executors.newFixedThreadPool(4);
Executors type2Runnables = Executors.newFixedThreadPool(4);
etc..
2. Submit tasks to it
for(){
type1Runnables.submit(new Runnable1());
type2Runnables.submit(new Runnable2);
}
3. Invoke the executors
type1Runnables.invokeAll();
type2Runnables.invokeAll();
To make it more generic you could perhaps write your own executorservicefactory which accepts the different runnable types.

Categories

Resources