Return Value from Java Thread Class - java

So below is a simple Java class using multithreading, and my question is, is there a way for me to store the randomNumber from each thread (maybe in a variable called randomNumberOne or randomNumberTwo), so that I can use those to possibly get the sum of both and return it?
I know this example sounds stupid but basically with my real code I am returning a value from each of my threads and want to get the average of them. I haven't found any solution for returning values in threads in java (also I am new to multithreading completely).
public class Example {
public static void main(String[] args){
MathThread one = new MathThread();
MathThread two = new MathThread();
one.start();
two.start();
}
}
class MathThread extends Thread{
public MathThread(){
}
public void run(){
Random rand = new Random();
int randomNumber = rand.nextInt((100 - 1) + 1) + 1;
System.out.println(randomNumber);
}
Output
5
33

Add a result variable to your MathThread class and get the value after you join the thread:
class MathThread extends Thread
{
private int result;
public int getResult()
{
this.join();
return result;
}
public void run()
{
// ...
result = randomNumber;
}
}
one.start();
two.start();
double average = (one.getResult() + two.getResult()) / 2.0;

In Java 8 you can do
IntStream.of(0, 2).parallel()
.map(i -> new Random().nextInt(100)+1)
.forEach(System.out::println);
Without using the Stream API you can do
List<Future> futures = new ArrayList<>();
for (int i = 0; i < 2; i++)
futures.add(ForkJoinPool.commonPool()
.submit(new Callable<Integer>() {
public Integer call() {
return new Random().nextInt(100)+1;
}));
for(Future<Integer> future : futures)
System.out.printl(future.get());

Here is the simple snippet to customize:
// 1. Create and fill callables to execute
List<Callable<Integer>> callables = new LinkedList<>();
// callabels.addAll(makeMeCallables());
// 2. Run using Executor of your choice
ExecutorService service = Executors.newCachedThreadPool();
List<Future<Integer>> results = service.invokeAll(callables);
// 3. Get the results
if (results.get(i).isDone()) {
Future f = result.get(i);
// process f.get()
}

Related

Converting Runnable into an array of runnable Workers

I am trying to create a runnable array that stores worker classes then use a Thread array to start the works.
public class SimpleThreads {
public static void main(String[] args) {
System.out.println("main starts.");
int num1 = 5;
int num2 = 7;
// create Workers
Runnable r1 = new Worker(num1, num2);
Runnable r2 = new Worker(num1 * 10, num2 * 10);
Runnable[] runs = new Worker(num1, num2);
// create Threads to run Workers
Thread[] threads = new Thread[args.length];
for (int i = 0; i < args.length; i++) {
threads[i] = new Thread(runs[i]);
}
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
// start threads
t1.start();
t2.start();
// Returns the adition to the main
System.out.println(((Worker) r1).doCalc());
System.out.println(((Worker) r2).doCalc());
int grandTotal = 0;
grandTotal = ((Worker) r1).doCalc() + ((Worker) r2).doCalc();
System.out.println("The Grand Total " + grandTotal);
System.out.println("main ends.");
}
}
/*
* the class that becomes a thread, can be named anything, must have
* "implements Runnable" which requires the public void run() method
*/
class Worker implements Runnable {
private int val1;
private int val2;
private long threadId;
// constructor
Worker(int val1, int val2) {
this.val1 = val1;
this.val2 = val2;
}
// required method
public void run() {
threadId = Thread.currentThread().getId();
doCalc();
}
// does the actual work
public int doCalc() {
return val1 + val2;
// System.out.printf("[%03d] %3d + %3d = %3d\n", threadId, val1, val2, result);
}
}
Basically, can someone help me figure out what I am doing wrong here? I get this error Type mismatch: cannot convert from Worker to Runnable[]Java(16777233)
My Expected results should be
Creating an array of runnable workers
Then using that array of runnable workers with my thread array and starting threads automatically, instead of hardcoding each thread 1 by 1.
It seems you are a little mixed up in concepts.
You store all your threads and runnables in arrays, but then you go ahead and create non-array instances and use those.
You declare runnables and threads, but then you go ahead and call the calculation method straight from your main thread.
Let's clean up the startup part first:
public class SimpleThreads {
public static void main(String[] args) {
System.out.println("main starts.");
int num1 = 5;
int num2 = 7;
// Build an array of workers.
Worker[] workers = new Worker[] {
new Worker(num1, num2),
new Worker(num1 * 10, num2 * 10)
};
// create Threads to run Workers and start them
Thread[] threads = new Thread[workers.length];
for (int i = 0; i < workers.length; i++)
{
threads[i] = new Thread(workers[i]);
threads[i].start();
}
So, now we have an array of Workers and an array of Threads.
You could declare the workers array to be of type Runnable if you wish, but we want to use the worker's methods later.
Lets see if we can get data out of the workers. We'll add a getResult() method.
class Worker implements Runnable {
private int val1;
private int val2;
private int result;
// constructor
Worker(int val1, int val2) {
this.val1 = val1;
this.val2 = val2;
}
// required method
public void run() {
doCalc();
}
// does the actual work
private void doCalc() {
result = val1 + val2;
}
public int getResult() { return result; }
}
So, once our worker has completed, we can call getResult() to see what it's final answer is.
So, back to the main, let's wait for the threads to finish, and then add up their results.
int grandTotal = 0;
// Wait for threads to finish
for(int i=0;i<threads.length;i++)
{
threads[i].join();
}
// Read their results
for (int i=0; i<workers.length;i++)
{
grandTotal += workers[i].getResult();
}
System.out.println("The Grand Total " + grandTotal);

How to synchronise threads and preserve their execution order with CyclingBarrier?

I want to write a multithread app that prints characters from Strings one by one and after first "round" it would preserve order for the other rounds. It should work somehting like this:
For Strings:
private String[] strings = {"aaaa", "bb", "ccccccccccccc", "dddddd"};
It would print:
abcd abcd acd acd cd cd c c c c c c c
or maybe
dbac dbac dac dac dc dc c c c c c c c
depending on which proccess started first in the very first round
My solution so far looks like this
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Printer {
private CyclicBarrier cyclicBarrier;
private final static String one = "aaa";
private final static String two = "bbbb";
private final static String three = "c";
private final static String four = "dddddd";
public static void main(String[] args) {
Printer printer = new Printer();
printer.runSimulation(4);
}
private void runSimulation(int numberOfStrings) {
cyclicBarrier = new CyclicBarrier(numberOfStrings, new AggregatorThread());
Thread thread = new Thread(new PrintingThread(padSpaces(one, 10)));
Thread thread1 = new Thread(new PrintingThread(padSpaces(two, 10)));
Thread thread3 = new Thread(new PrintingThread(padSpaces(three, 10)));
Thread thread4 = new Thread(new PrintingThread(padSpaces(four, 10)));
thread.start();
thread1.start();
thread3.start();
thread4.start();
}
class AggregatorThread implements Runnable{
#Override
public void run() {
System.out.print(" ");
}
}
class PrintingThread implements Runnable{
private String toPrint;
private int iterator;
public PrintingThread(String toPrint) {
this.toPrint = toPrint;
this.iterator = 0;
}
#Override
public void run() {
while(iterator < toPrint.length()) {
System.out.print(toPrint.charAt(iterator));
iterator++;
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
private String padSpaces(String inputString, int length) {
if (inputString.length() >= length) {
return inputString;
}
StringBuilder sb = new StringBuilder();
while (sb.length() < length - inputString.length()) {
sb.append(' ');
}
StringBuilder sb1 = new StringBuilder(inputString);
sb1.append(sb);
return sb1.toString();
}
}
But it doesn't preserve the order of letters written to the console and also i fill the Strings to the some hardcoded value right now, but i would want to make it work properly without equal strings.
Any suggestions on this?
Since you're asking for a solution with CyclicBarrier, here's a way you could do this with one... It definitely wouldn't be my first thought for how to solve the issue though (assuming the issue isn't 'do this with a CyclicBarrier'...).
Create a CyclicBarrier of length 4.
Assign each Thread a number (0 to 3) when it starts (using an AtomicInteger or otherwise).
Have each Thread do something like:
while (barrier.getNumberWaiting() != this.threadNumber) {
}
// Do your adding to the StringBuilder here...
barrier.await();
I.e. each Thread spins until the number of waiting parties is equal to that Thread's number.
Whichever is assigned 0 will always go through first, while all the others are stuck spinning. Once that Thread has done its StringBuilder thing, it will then await, which in turn frees the Thread assigned 1 to go through. The order will stay consistent after the number assignments.
To get the unique id per process, a simple AtomicInteger can be used.
private final AtomicInteger idCounter = new AtomicInteger();
private final CyclicBarrier barrier = new CyclicBarrier(4);
private final AtomicInteger doneCounter = new AtomicInteger();
public Runnable createRunnable() {
return () -> {
final int threadId = this.idCounter.getAndIncrement();
boolean threadDone = false;
boolean moreCharacters = true;
while (true) {
while (this.barrier.getNumberWaiting() != threadId) {
}
// Add to StringBuilder here...
// Set the 'moreCharacters' flag as false once this thread
// has handled its String.
// They will still need to spin though, to make sure the
// parties waiting keep adding up as appropriate.
if (!moreCharacters && !threadDone) {
// 'threadDone' used so that each thread only
// increments the 'doneCounter' once.
this.doneCounter.incrementAndGet();
threadDone = true;
}
barrier.await();
if (this.doneCounter.get() == 4) {
// Exit out of the loop once all Threads are done.
break;
}
}
};
}

Prime Numbers Generating Threads in Java printing twice

I am trying to print prime numbers between one point to another, lets say from 1 to 1000 in one thread and 1000 to 2000 in another thread but when I print each thread using foreach loop it gives me an unordered Arraylist which is printed twice.
I am trying to print 1, 2, 3, 5, 7... using two concurrent threads. Please help me out so that I can better understand threading.
public class PrimeNumberGenerator implements Runnable{
protected long from, to;
static ArrayList<Long> primeList = new ArrayList<Long>();
public PrimeNumberGenerator(long from,long to)
{
this.from = from;
this.to = to;
}
public long count = 0;
public void run() {
for(long n=from; n<=to; n++){
boolean isPrime = true;
for(long i = 2; i<n; i++) {
if(n % i==0) {
isPrime = false;
break;
}
}
if(isPrime) {
count++;
primeList.add(n);
}
}
}
public ArrayList<Long> getPrimes() {
return primeList;
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
PrimeNumberGenerator gen1 = new PrimeNumberGenerator(1L,1000L);
PrimeNumberGenerator gen2 = new PrimeNumberGenerator(1001L,2000L);
Thread t1 = new Thread(gen1);
Thread t2 = new Thread(gen2);
t1.start();
t2.start();
t1.join();
t2.join();
gen1.getPrimes().forEach(primeList -> System.out.println(primeList));
gen2.getPrimes().forEach(primeList -> System.out.println(primeList));
}
}
The problem is that you have two threads filling the same ArrayList at the same time, because your ArrayList is static (meaning there will only be one instand shared throughout the whole application)
The first thread may add three numbers, then the second thread adds three numbers and then the first again, resulting in an ArrayList that contains
[1, 2, 3, 1009, 1013, 1019, 5, 7, 11]
Then in the end you (correctly) wait for the Threads to finish and print the same (incorrectly ordered) ArrayList twice!
Just make your ArrayList non static and it will work, that way both PrimeNumberGenerator will have their own ArrayList!
I recommend using a TreeSet to keep the primes ordered. The TreeSet will need to be properly synchronized for multiple thread access.
public class PrimeNumberGenerator implements Runnable {
protected long from, to;
static Set<Long> primeList = new TreeSet<Long>();
public PrimeNumberGenerator(long from, long to)
{
this.from = from;
this.to = to;
}
public long count=0;
public void run() {
for(long n=from;n<=to;n++) {
boolean isPrime = true;
for(long i = 2; i<n; i++) {
if(n % i==0) {
isPrime = false;
break;
}
}
if(isPrime) {
count++;
synchronized(primeList) {
primList.add(n);
}
}
}
}
public static ArrayList<Long> getPrimes(){
//Make a copy so we don't need to synchronize outside of this class
return new ArrayList<>(primeList);
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
PrimeNumberGenerator gen1 = new PrimeNumberGenerator(1L,1000L);
PrimeNumberGenerator gen2 = new PrimeNumberGenerator(1001L,2000L);
Thread t1 = new Thread(gen1);
Thread t2 = new Thread(gen2);
t1.start();
t2.start();
t1.join();
t2.join();
PrimeNumberGenerator.getPrimes().forEach(primeList -> System.out.println(primeList));
}
}

how to spwan recursive calls and for loop iterations in multiple threads in java (if possible)?

I was wondering if it is possible to spawn each loop iteration (each iteration into a thread by itself) and finally collect the result. consider this example, nothing fancy in it at all. Just a simple for-loop, but the idea is to extend on it. The body of for loop does not matter, I just filled up with some code. but basically assume it has some expensive calculation which will take few minutes to complete for each iteration. so I want to do each loop calculation in a separate thread.
public class Threadspawns {
private double[] arr = new double[4];
public void calculations(){
for (int i =2; i < 6; i++){
//expensive calculation
arr[i-2]=Math.pow(i,500);
}
}
public static void main(String[] args){
Threadspawns t = new Threadspawns();
long start = System.currentTimeMillis();
t.calculations();
long end = System.currentTimeMillis();
System.out.println(Arrays.toString(t.arr));
System.out.println("time taken "+ (end-start));
}
}
on the same note,
if it is possible to actually split the recursive calls into multiple threads and collect them as they return.
Example is that of fibonacci
public static int fibonacci(int n){
if (n==0)
return 0;
if (n==1)
return 1;
return fibonacci(n-2)+fibonacci(n-1);
}
It is possible that it cannot be done for fibonacci recurive method. but any other example of paralleling recursive calls between threads IF POSSIBLE would be nice to know.
P.S: I have basic knowledge of Thread and Runnable, but wondering if the above is doable
Solution to your first requirement that is moving the expensive calculation into a Callable task. Hope it find it useful:
import java.util.Arrays;
import java.util.concurrent.*;
public class Threadspawns {
private final int THREAD_COUNT = 8;
private final int CALCULATION_COUNT = 60000;
private double[] arr = new double[CALCULATION_COUNT];
public void calculations() {
ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);
ExecutorCompletionService<Double> completionService = new ExecutorCompletionService<Double>(executorService);
for (int i = 2; i < CALCULATION_COUNT; i++) {
completionService.submit(new Calculation(i));
}
//Get from all Future tasks till all tasks completed
for (int i = 2; i < CALCULATION_COUNT; i++) {
try {
arr[i] = completionService.take().get();
} catch (InterruptedException e) {
e.printStackTrace(); //do something
} catch (ExecutionException e) {
e.printStackTrace(); //do something
}
}
}
private static class Calculation implements Callable<Double> {
private final int num;
private Calculation(int num) {
this.num = num;
}
#Override
public Double call() throws Exception {
return Math.pow(num, 500);
}
}
public static void main(String[] args) {
Threadspawns t = new Threadspawns();
long start = System.currentTimeMillis();
t.calculations();
long end = System.currentTimeMillis();
System.out.println(Arrays.toString(t.arr));
System.out.println("time taken " + (end - start));
}
}

Multi threads in Java

I have some class. For example:
public class Data {
private String name;
public Data(String url) {
// There is download something from the Internet and set field "name".
}
public String getName() {
return name;
}
}
In some method I need to initialize array of objects Data.
ArrayList<Data> list = new ArrayList<Data>;
for(int i=0; i<max; i++) {
list.add(new Data("http://localhost/" + String.valueOf(i)));
}
But it is to long. I wanna do this:
final ArrayList<Data> list = new ArrayList<Data>;
for(int i=0; i<max; i++) {
final int tmp = i;
new Thread() {
public void run() {
list.add(new Data("http://localhost/" + String.valueOf(tmp)));
}
}.start();
}
But the main thread ends sooner than the others and variable list is empty. What should I do? Help pls :)
UP. That is not too fast to download some data from the Internet that's why I've created several threads.
Instead of dealing with the low level details of the Thread API, you could use the java concurrent package, with an executor to handle the threads (I don't know what ListArray is but if it is not thread safe you will have issues with the solution proposed some of the other answers: adding a join will not be sufficient).
For example, a simplified example would be:
final ExecutorService executor = Executors.newFixedThreadPool(10);
final List<Future<Data>> list = new ArrayList<Future<Data>>(max);
for (int i = 0; i < max; i++) {
final int tmp = i;
Callable<Data> c = new Callable<Data>() {
#Override
public Data call() {
return new Data("http://localhost/" + tmp);
}
};
list.add(executor.submit(c));
}
executor.shutdown();
for (Future<Data> future : list) {
Data data = future.get(); //will block until the page has been downloaded
//use the data
}
Ideally, you whould add some error handling around future.get(), as it will throw an ExecutionException if your task throws an exception, which I suppose could happen if the page is not availble for example.
1. When you fire the Another thread, that does the work of getting the data from net and populating the list, immediately after that use join() method.
2. join() method will not let the next line to execute before the run() method of the thread on which it is called has finish().
3. So your main() method will not be executed before the list is populated as you have used join() to hold the execution before the other thread is done.....
In your main use Thread.join to wait for the child threads to complete
Thread[] threads = new Thread[max];
final List<Data> list = Collections.synchronizedList(new ArrayList<Data>());
for(int i=0; i< max; i++) {
final int tmp = i;
Thread t = new Thread() {
public void run() {
list.add(new Data("http://localhost/" + String.valueOf(tmp)));
}
};
t.start();
threads[i] = t;
}
for (Thread t : threads) {
t.join();
}

Categories