Creating three threads in Java to compute three different items - java

I'm trying to write my solution to a problem of multithreading in Java:
Create three separate threads that will calculate the average, minimum
and maximum of a series of numbers that is passed to the program. The
values will be stored globally in the program. The three threads will
return the three values respectively to the main program where it will
be output to the user.
I'm new to Java, so I've got one basic question about the approach to this program: How do I create three separate threads that will perform three different functions? While reading multithreading, I've come across several examples wherein three(or more) threads were created which would each execute a single function: counting down a loop. Thus requires only a single call to public void run() and one can very easily create three instances of a class that implements Runnable to do this, something like:
// Create multiple threads.
class NewThread implements Runnable {
String name; // name of thread
Thread t;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(name + "Interrupted");
}
System.out.println(name + " exiting.");
}
}
class MultiThreadDemo {
public static void main(String args[]) {
new NewThread("One"); // start threads
new NewThread("Two");
new NewThread("Three");
try {
// wait for other threads to end
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
I am not sure how to create threads that perform separate functions: calculate double, min and max. So far, I've created one thread that calculates the average and returns it to the main program. This is my code [till now]:
package assignment2;
class Q2Thread implements Runnable {
String name;
Thread t;
private int average;
int sum=0;
Q2Thread(String name)
{
this.name=name;
t=new Thread(this, name);
//System.out.println("This thr");
t.start();
}
public void run()
{
try
{
for(int i=0;i<Q7Main.arr.length;i++)
sum+=Q7Main.arr[i];
average=sum/Q7Main.arr.length;
}
//catch(InterruptedException e)
finally
{
System.out.println("Calcuated average.");
}
System.out.println("Child Thread exiting.");
}
public int getAverage()
{
return average;
}
}
package assignment2;
import java.util.*;
public class Q7Main {
public static int[] arr=new int[5];
static Scanner in=new Scanner(System.in);
private static int finalAverage;
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Please enter the numbers: " );
for(int i=0;i<arr.length; i++)
arr[i]=in.nextInt();
System.out.println("You entered the numbers: ");
for(int x: arr)
{
System.out.print(x+ " ");
}
System.out.println();
Q2Thread obj=new Q2Thread("Average");
try
{
obj.t.join();
}
catch(InterruptedException e)
{
System.out.println("Interrupted.");
}
finalAverage=obj.getAverage();
System.out.println("The average of the numbers is: "+ finalAverage);
}
}
I have two questions now:
Can someone give me the approach to creating two more threads that will compute the min and max?
Are there any OOP defects in my code(thus far) that I should be aware of?

What you can do is create two other classes that calculate min and max, create an object of each of them obj1 and obj2. Since the constructor starts the thread for you, you should now have 3 threads running asynchronously.
Call obj1.t.join() and obj2.t.join() within that try block. So it should look like this:
try{
obj.t.join();
obj1.t.join();
obj2.t.join();
}
catch(InterruptedException e)
{
System.out.println("Interrupted.");
}
int average = obj.getAverage();
int max = obj1.getMax();
int min = obj2.getMin();
And then do whatever you want with these numbers.
As for some general comments, firstly I would not have a thread object as an attribute within the runnable class, nor have the start() method within the constructor. Instead, within the main class, I would encourage you to create three thread objects with an instance of each runnable class, and then invoke the start() method on each of them. Furthermore, instead of the three runnable
classes all interacting with the same static array found in Q7Main, I would instead update their
constructors to accept the array as a parameter in the constructor, and then have each of them interact with a unique array object when their run method is invoked. Otherwise, you have an issue that when one thread changes the value of something in the array, you get unexpected results.
Of course in this case none of your classes do that, but its something to keep in mind.
For example
Q2Thread obj =new Q2Thread("Average", arr);
Q2MaxThread obj1 = new Q2MaxThread("Maximum", arr);
Q2MinThread obj2 = new Q2MinThread("Minimum", arr);
Thread avThread = new Thread(obj);
Thread maxThread = new Thread(obj1);
Thread minThread= new Thread(obj2);
avThread.start();
maxThread.start();
minThread.start();
try{
avThread.join();
maxThread.join();
minThread.join();
}
catch(InterruptedException e)
{
System.out.println("Interrupted.");
}
int average = obj.getAverage();
int max = obj1.getMax();
int min = obj2.getMin();

Further to the #ElvenAshwin answer you should probably take three classes as private inner class.... good practice as you build bigger things you dont pollute public api. As an alternate and good exercise, think about doing it with lambdas in java 8. Its just a function you need not the class.

Related

How to ensure execution order of threads [duplicate]

This question already has answers here:
How threads are executed in the memory?
(2 answers)
Closed 2 years ago.
This is a simplified version of the problem. Given n number of threads, each printing a constant number all the time. For example, Thread-1 should always print 1, Thread-2 should always print 2 and so on...
How to ensure, the threads are executed in order i.e. the output should be as below:
Thread-1: 1
Thread-2: 2
Thread-3: 3
.
.
.
Thread-n: n
I have a naïve solution to do it through wait()/notify() but I guess there might be a better solution than that. Perhaps, using Semaphore maybe? I don't know.
Update:
Based on the answers received, I think I was not very clear. There are some constraints:
All threads should start at once (assume we don't really have control on that)
Once all the threads start, there should be some sort of communication between the threads to execute in order.
This sequentially execution of thread can be handled beautifully using Thread.join() method. To handle it properly, you may have to create MyRunnable(or, use any name you prefer) which implements Runnable interface. Inside MyRunnable, you can inject a parent Thread, and call parent.join() at top of MyRunnable.run() method. The code is given below:
public class SequentialThreadsTest {
static class MyRunnable implements Runnable {
static int objCount; // to keep count of sequential object
private int objNum;
private Thread parent; // keep track of parent thread
MyRunnable(Thread parent) {
this.parent = parent;
this.objNum = objCount + 1;
objCount += 1;
}
#Override
public void run() {
try {
if(parent != null) {
parent.join();
}
System.out.println("Thread-" + objNum + ": " + objNum);
} catch(InterruptedException e) {
e.printStackTrace();
// do something else
} finally {
// do what you need to do when thread execution is finished
}
}
}
public static void main(String[] args) {
int n = 10;
Thread parentThread = null;
for(int i=0; i<n; i++) {
Thread thread = new Thread(new MyRunnable(parentThread));
thread.start();
parentThread = thread;
}
}
}
And the output is:
Thread-1: 1
Thread-2: 2
Thread-3: 3
Thread-4: 4
Thread-5: 5
Thread-6: 6
Thread-7: 7
Thread-8: 8
Thread-9: 9
Thread-10: 10
You haven't specified many details, but if you only want serializable thread execution you can wait for previous thread to finish and then print. Something like this:
public static void main(String[] args) {
Thread thread = null;
for (int i = 0; i < 10; i++) {
int index = i;
Thread previousThread = thread;
thread = new Thread(() -> {
if (previousThread != null) {
try {
previousThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(index);
});
thread.start();
}
}
Try making a queue - this will do exactly what you want. Simply change the value of n to however many threads you have, and add all the threads sequentially (only once). If ever you want to stop the threads from executing, all you have to do is add end to the queue. Obviously, for a larger project, you will need to modify this code a little bit (I would recommend replacing the main method with a class initializer and pass the LinkedBlockingQueue as a pre-built argument)
import java.util.concurrent.LinkedBlockingQueue;
public class HelloWorld{
private static int n = 2;
private static LinkedBlockingQueue<Thread> queue = new LinkedBlockingQueue<>(n+1);
static Thread a = new Thread(()->{
System.out.print("a");
});
static Thread b = new Thread(()->{
System.out.print("b");
});
static Thread end = new Thread(()->{
break_ = true;
});
public static final int END = 20;//this and the counter are just here so the code doesn't run forever
public static volatile int i = 0;
public static volatile boolean break_ = false;
public static void main(String []args){
queue.add(a);
queue.add(b);
//queue.add(end);
outerloop:
while(true){
Thread toBeRun = queue.poll();
try{
toBeRun.run();
queue.add(toBeRun);
i++;
if(i>=END || break_){//i>=END does not need to be here, it's just to stop it from running forever in this example
break;
}
}catch(NullPointerException e){
break;
}
}
}
}
Note: This uses java 8 lambdas. If you're using an older version of java, you will need to create the threads using the run method.

java printout elements from arrays one by one into separate lines using multi thread and for loop

Sorry for my lacking english. I am not a native english speaker.
Today I learned about thread and now I am training.
I want to make a program which prints out elements from arrays one by one into separate lines using multi thread
package Teeest;
import java.util.Arrays;
public class THREADTEST {
public static void main (String[] args){
int[]a1 ={1,5,7,2,8,1,1,3,6};
int[]a2 = {2,6,1,7,4,8,2,1,7};
Thread2 t1 = new Thread2(a1,5);
Thread2 t2 = new Thread2(a2,10);
t1.thr.start();
t2.thr.start();
t1.thr.interrupt();
t2.thr.interrupt();
}
}
class Thread2 implements Runnable {
Thread thr = new Thread(this);
private int []array;
private int interval;
Thread2(int[] ar, int time) {
array = ar;
interval = time*1000;
}
public void run(){
while(true){
try{
Thread.sleep(interval);
}
catch(InterruptedException e){}
for(int a: array){
System.out.print(array[a]+" ");
}
}
}
}
This is my code and my output prints out whole arrays directly and even two arrays are not seperated into different lines. (I know I can use "\n" but in this case this does not work so well )
But I want java prints out elements one by one and into two different lines. How should I think?
_____________(line for elements from ar1)
(Enter) (Separate line)
_____________(line for elements from ar2) Of course thread should work while printing out elements one by one.
Basically you just want the output of array1 on a line and the output of array2 on another line.
To do so, I would store the result in a StringBuilder for each Thread.
public void run(){
while(true){
try{
Thread.sleep(interval);
}
catch(InterruptedException e){}
StringBuilder sb = new StringBuilder();
for(int a: array) {
sb.append(array[a] + " ");
}
System.out.println(sb.toString());
}
}
and you can remove this line
Thread thr = new Thread(this);
and call directly
t1.start();
t2.start();
and I do not understand the call to
t1.interrupt();
Hope it helps

how can I get array values back from a thread

I have a thread, in Java, putting the first 100 Fibonacci numbers in an array. How do I get the numbers back from the thread. Is there an interrupt, handling, exception, implements, extends? I have been adding things and the trial and error is not getting me anywhere to understanding.
import java.util.Scanner;
import java.io.*;
import java.lang.Thread; //don't know if this is needed
public class FibThread extends Thread{
public FibThread (){
super();
}
public void run(int inputNum){
System.out.println(inputNum);
long[] fibArray = new long[inputNum];
fibArray[0]=0;
fibArray[1]=1;
fibArray[2]=1;
for(int i = 3; i<inputNum; i++){
fibArray[i]= fibArray[i-1] + fibArray[i-2];
// }
//System.out.println( );
// for(int j = 0; j<= inputNum; j++){
int output = (int) fibArray[i];
System.out.println(output);
}
}
public static void main(String[] args){
Scanner keyboard = new Scanner(System.in);
FibThread threadOne;
int inputNum, itter, output;
System.out.println("Please enter the number of Fibonacci numbers to be generated: ");
itter = keyboard.nextInt();
//inputNum = itter;
threadOne = new FibThread();
threadOne.start();
// for(int j = 0; j<= inputNum; j++){
// int output = (int) fibArray[j];
// System.out.println(output);
}
}
If you have a "task" that returns a value, make it a Callable.
If you want the callable to run in a background thread, then instead of handling the creation and execution of threads yourself, it's generally better to abstract this through an ExecutorService. A caller can interact with the service by passing in a Callable, and getting back a Future that will be populated with the value when the calculation has completed.
To modify your example, renaming FibThread to FibCalc:
public class FibCalc implements Callable<Integer> {
// We need some way to pass in the initial input - must be through the
// constructor and we'll store it here
private final inputNum;
public FibCalc(int inputNum) {
this.inputNum = inputNum;
}
public int call() {
// The same as your run() method from before, except at the end:
...
return output;
}
}
// And now for your main() method
public static void main(String[] args) throws Exception {
// As before up to:
...
itter = keyboard.nextInt();
// Create a very simple executor that just runs everything in a single separate thread
ExecutorService exec = Executors.newSingleThreadExecutor();
// Create the calculation to be run (passing the input through the constructor)
FibCalc calc = new FibCalc(itter);
// Send this to the executor service, which will start running it in a background thread
// while giving us back the Future that will hold the result
Future<Integer> fibResult = exec.submit(fibCalc);
// Get the result - this will block until it's available
int result = fibResult.get();
// Now we can do whatever we want with the result
System.out.println("We got: " + result);
}
If you absolutely have to create a Thread object yourself (due to artificial constraints on a homework question, or something like that - I can't see why one would realistically do this in reality), then the approach has to be different. You can't return a value because run() must return void due to the interface. So my approach here would be to store the result in a local variable of the FibThread class, and then add a method to that class (e.g. public int getResult()) which returned that variable.
(If you're doing it this way, bear in mind that you'll have to handle the concurrency issues (i.e. letting the caller know the result is ready) yourself. A naive approach, where the main method starts the thread and then immediately calls getResult(), means that it will almost certainly get an "empty" result before the calculation has finished. A crude solution to this problem would be calling join() on the spawned thread, to wait for it to finish before accessing the result.)

Synchronizing threads

So I have a code:
public void runThreads(int number)
{
List<Thread> threadList = new ArrayList<Thread>();
for (int i = 0; i < number; i++)
{
Thread t = new MyThread(getRandomPerson(),i);
threadList.add(t);
}
for (Thread x : threadList)
{
x.start();
}
}
So I am adding threads to my list of threads and then starting this threads.
This is MyThread class:
public class MyThread extends Thread
{
Person person;
int number;
public MyThread(Person person, int number)
{
this.person = person;
this.number = number;
}
#Override
public void run()
{
try
{
synchronized (this)
{
Thread.sleep(1000);
System.out.println(number + "\t" + person.getSurname());
Thread.sleep(1000);
System.out.println(number + "\t" + person.toString());
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
I wanted to make a program which creates the threads, adds them to the list, invokes them but each thread should wait until the previous ended its task.
So output should be like :
1 Surname
/** Waitning second */
1 person.toString()
/** Waiting second*/
And then the second thread start invoking:
2 Surname
....
How to achieve this using synchronized? I tried different ways to use synchronized but it failed.
public class MyThread extends Thread
{
private static Object lock = new Object();
...
synchronized (lock)
{
Thread.sleep(1000);
System.out.println(number + "\t" + person.getSurname());
Thread.sleep(1000);
System.out.println(number + "\t" + person.toString());
}
...
That way you will get the same person's surname and toString() in order. You won't enforce strict ordering on the people, person 7 may still go before person 1.
You need a common lock - at the moment you are synchronizing on this, which is different for each thread. Try something like:
private static final Object lock = new Object();
and synchronize on that static (therefore shared) variable instead.
If you must use threads and if you must have order of execution, then you can do a t.join() immediately after t.start() - this will ensure the following flow:
- Main Thread
- loop
- start child thread
- wait for child thread to finish
- continue loop
- Exit Main thread
But, as pointed before, you don't need threads to do this since you can see that there is absolutely no gain from this approach (apart from academical) and it's detrimental in fact.
And special thanks to #assylias.

in Java I have to take array and use that value to increment one time and decrement two times using threads

I am coding for a program whose detail is:
1. User enter the value in array and in program automatically entered value times 0 should be inserted in each index.
2. Use threads, first thread calls it decrement(2) in the user entered value and then it goes to sleep for 1 second.
As sleep calls then second thread calls it put a increment of 1 and then sleep goes for 2 seconds then again first thread call it again decrement in the incremented value and so on until the value of decremented thread equals to zero.
As value of decrement equal to zero then incrementing automatically must stop.
I have the code now help me if any one has understand my question...
All comments should be appreciated..
//Through Implementing Runnable Interface
//Create a second thread
//import java.util.Scanner;
class NewThread extends Thread implements Runnable {
Thread t;
NewThread(){
//Create a new, second thread
t = new Thread(this, "Demo AASSINGMENT");
//System.out.println("Child Thread: "+ t);
t.start();//Start the thread
}
//This is the entry point for the second thread.
public void run(){
try{
for(int i = 10; i>0; --i){
System.out.println("Decrement: " +i);
//i--;
//System.out.println("Child Thread 2nd dec: " + i);
Thread.sleep(1000);
}
}
catch(InterruptedException e){
System.out.println("Decrement INterrupted");
}
System.out.println("Oops!! -- Decreasing Value is less than or equal to zero");
}//run
}//class
class ThreadDemo {
public static void main(String args[]){
new NewThread();//create a new thread
int[] arr; int dj;
// Scanner input = new Scanner(System.in);
// System.out.print("Enter Your Desired Value : ");
//int z = input.nextInt();
try{
//arr = new int[z];
//for(dj =0; dj<array.length;dj++)
//{
// array[dj]=0;
// System.out.println("0's inserted "+ array[dj]);
//}
//while(z!=0){
for(int i = 10; i<=14; i++){
System.out.println("Increment: " +i);
//if(i>6){
//System.out.println("Main Thread Exiting");}
Thread.sleep(2000);
}//for
}//try
catch(InterruptedException e){
System.out.println("Main Thread Interrupted");
}
System.out.println("Increasing Value has exceeded from 14 so Exiting");
}//main
}//class
In your main method, you create an instance of newThread, but you never start it. Unless you start it, it will never execute.
Edit to provide more implementation info
As a precursor to the following explanation, normally you don't have your classes extend Thread. Instead, implement Runnable then create a standard Thread instance that executes your Runnable instance.
So, I would suggest that you modify the code as follows:
class NewRunnable implements Runnable
{
public void run()
{
// Do important background stuff here
}
}
public static void main (String[] args)
{
Thread thr = new Thread ( new NewRunnable( ) ) ;
thr.start( ) ;
// Do other important stuff
}

Categories