Barrier Synchronization (Output, increment and wait) - java

I want to make synchronized threads wait for each other. In the example program, each thread simply counts up to 100. I want the threads to wait every 10 outputs.
Because I am preparing for an exam, I would like to use the CyclicBarrier method.
Here is the code:
public class NumberRunner extends Thread {
private int number;
private CyclicBarrier barrier;
public NumberRunner(int n, CyclicBarrier b) {
number = n;
barrier = b;
}
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("Thread " + number + ": " + i);
}
}
and the Main-Class
public class Barriers {
private final static int NUMBER = 3;
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3);
NumberRunner[] runner = new NumberRunner[NUMBER];
for (int i = 0; i < NUMBER; i++) {
runner[i] = new NumberRunner(i, barrier);
}
for (int i = 0; i < NUMBER; i++) {
runner[i].start();
}
}
How do I insert the barriers?

for (int i = 0; i < 100; i++) {
System.out.println("Thread " + number + ": " + i);
if ((i + 1) % 10 == 0) {
try {
barrier.await();
} catch () {}//whatever exceptions b.await() throws
}
}

Related

Multi-Threaded Java Based Prime Number Generator

I am working on a prime number generator that is multi-threaded. My goal for this multi-threaded process is that each process will check a single number. I do have somewhat working code, but I am having some issues with the "locking" concept in where the schedular is running 2 process's very closely to each other.
Claimed Lock: 0; Claimed Number: 75827; isPrime: false
Claimed Lock: 1; Claimed Number: 75829; isPrime: false
Claimed Lock: 2; Claimed Number: 75831; isPrime: false
Claimed Lock: 4; Claimed Number: 75835; isPrime: false
Claimed Lock: 5; Claimed Number: 75837; isPrime: false
Claimed Lock: 5; Claimed Number: 75837; isPrime: false
Claimed Lock: 3; Claimed Number: 75833; isPrime: true
Claimed Lock: 6; Claimed Number: 75839; isPrime: false.
(you can see that 2 locks - i.e. 5 get called twice - they should be disctinct)
My main goal of this program is to have 1 thread calculate 1 based prime numbers. There will be n number of threads based on what Java JVM reports back to the int cores variable inside of the code.
Here is a quick explanation of my program:
The program starts out getting the number logical cpu cores of the given computer
Creates a 2d Array of [2] [Num of CPU Cores]
Array[0][i] = Gets filled with 2k+1 (odd numbers) of potential prime numbers (doing this since 2 is the only known prime number that is even)
Array[1][i] = Gets filled with "-1" = Meaning that number is ready to be picked up by a process/thread
The program then spins up n number of threads (based on cpu core count)
A new thread that has been created is supposed to look for the next available Array[1][i] == -1 and change it to the value of 2. (2 represents a process lock and/or the number is being checked if prime or not)
-6a. The n number of child processes check if prime, and will change the Array[1][i] to either 1 or 0 (1 meaning it is prime or 0 meaning its not prime)
-6b. Child Process Terminates
Parent process - Main will busy wait until all Array[1][i] is either 1 or 0
Repeat back to step 3
What am I a missing or doing wrong with this logic? I believe I am missing something with the JVM/OS Schedular. But, I feel like I could be incorrect in this assumption as well? What could I do to remedy this issue?
Here is my Code:
Multi-Threaded Class
class MultithreadCalculate extends Thread {
public void run() {
try {
int indexNum = -1;
for (int i = 0; i < MultiThreadPrimeNumGen.cores; i++) {
if (MultiThreadPrimeNumGen.primeArray[1][i] == -1) {
MultiThreadPrimeNumGen.primeArray[1][i] = 2;
indexNum = i;
break;
}
}
boolean isPrime = true;
for (int i = 2; i < MultiThreadPrimeNumGen.primeArray[0][indexNum]; i++) {
if (MultiThreadPrimeNumGen.primeArray[0][indexNum] % i == 0) {
isPrime = false;
MultiThreadPrimeNumGen.primeArray[1][indexNum] = 0;
break;
}
}
if (isPrime) {
MultiThreadPrimeNumGen.primeArray[1][indexNum] = 1;
}
System.out.println("Thread " + Thread.currentThread().getId() + "; Claimed Lock: " + indexNum + "; Claimed Number: " + MultiThreadPrimeNumGen.primeArray[0][indexNum] + "; isPrime: " + isPrime);
}
catch (Exception e) {
System.out.println("Exception is caught");
}
}
}
Here is the main class:
public class MultiThreadPrimeNumGen {
public static int[][] primeArray;
public static int primeBase = 1;
public static int cores;
private static void fillArray() {
for (int i = 0; i < cores; i++) {
primeBase += 2;
primeArray[0][i] = primeBase;
}
for (int i = 0; i < cores; i++) {
primeArray[1][i] = -1;
}
}
public static void main(String[] args) throws FileNotFoundException {
File file = new File(System.getProperty("user.home") + "/Desktop" + "/PrimeNumber.txt");
PrintWriter out = new PrintWriter(file);
//Gets number of CPU Cores
cores = Runtime.getRuntime().availableProcessors();
System.out.println("Number of Cores: " + cores);
while (true) {
primeArray = new int[2][cores];
fillArray();
for (int i = 0; i < cores; i++) {
MultithreadCalculate multithreadCalculate = new MultithreadCalculate();
multithreadCalculate.start();
}
while (true) {
boolean flag = false;
for (int i = 0; i < cores; i++) {
if ((primeArray[1][i] == 0) || (primeArray[1][i] == 1)) {
flag = true;
} else {
flag = false;
break;
}
}
if (flag) {
break;
}
}
for (int i = 0; i < cores; i++) {
if (primeArray[1][i] == 1) {
out.println("PrimeNum: " + primeArray[0][i]);
out.flush();
}
}
}
}
}
So you want thread at the loop while filling the array:
Runnable run1 = new Runnable(){
public void run()
{
// Code to fill array
}
};
Thread thread1 = new Thread(run1);
thread1.start();
Runnable run2 = new Runnable(){
public void run()
{
// Code to fill array
}
};
Thread thread2 = new Thread2(run2);
thread2.start();
Actually, I solved my own idea without using Locks. The Idea Came from another user who posted on here: Prime Balpreet. So thank you! What I did was create getters and setters inside of the code. Here is the Modified code:
Multithreaded Class:
class MultithreadCalculate extends Thread {
int PrimeNumCalculate = -1;
int indexNum = -1;
public int getPrimeNumCalculate() {
return PrimeNumCalculate;
}
public void setPrimeNumCalculate(int primeNumCalculate) {
PrimeNumCalculate = primeNumCalculate;
}
public int getIndexNum() {
return indexNum;
}
public void setIndexNum(int indexNum) {
this.indexNum = indexNum;
}
public void run() {
try {
boolean isPrime = true;
for (int i = 2; i < getPrimeNumCalculate(); i++) {
if (getPrimeNumCalculate() % i == 0) {
isPrime = false;
MultiThreadPrimeNumGen.primeArray[0][getIndexNum()] = getPrimeNumCalculate();
MultiThreadPrimeNumGen.primeArray[1][getIndexNum()] = 0;
break;
}
}
if (isPrime) {
MultiThreadPrimeNumGen.primeArray[0][getIndexNum()] = getPrimeNumCalculate();
MultiThreadPrimeNumGen.primeArray[1][getIndexNum()] = 1;
}
System.out.println("Thread " + Thread.currentThread().getId() + "; Index: " + getIndexNum() + "; Number: " + getPrimeNumCalculate() + "; isPrime: " + isPrime);
}
catch (Exception e) {
System.out.println("Exception is caught");
}
}
}
Here is my Main Class:
public class MultiThreadPrimeNumGen {
public static int [][] primeArray;
public static int primeBase = 1;
public static int cores;
private static void fillArray() {
for (int i = 0; i < cores; i++) {
primeArray[0][i] = -1;
}
for (int i = 0; i < cores; i++) {
primeArray[1][i] = -1;
}
}
public static void main(String[] args) throws FileNotFoundException {
File file = new File(System.getProperty("user.home") + "/Desktop" + "/PrimeNumber.txt");
PrintWriter out = new PrintWriter(file);
cores = Runtime.getRuntime().availableProcessors();
System.out.println("Number of Cores: " + cores);
out.println(2);
out.flush();
while (true) {
primeArray = new int[2][cores];
fillArray();
for (int i = 0; i < cores; i++) {
MultithreadCalculate multithreadCalculate = new MultithreadCalculate();
multithreadCalculate.setPrimeNumCalculate(primeBase += 2);
multithreadCalculate.setIndexNum(i);
multithreadCalculate.start();
}
while (true) {
boolean flag = false;
for (int i = 0; i < cores; i++) {
if ((primeArray[1][i] == 0) || (primeArray[1][i] == 1)) {
flag = true;
} else {
flag = false;
break;
}
}
if (flag) {
break;
}
}
printMatrix(primeArray);
for (int i = 0; i < cores; i++) {
if (primeArray[1][i] == 1) {
out.println(primeArray[0][i]);
}
}
out.flush();
}
}
public static void printMatrix(int[][] arr) {
if (null == arr || arr.length == 0) {
return;
}
int idx = -1;
StringBuilder[] sbArr = new StringBuilder[arr.length];
for (int[] row : arr) {
sbArr[++idx] = new StringBuilder("[\t");
for (int elem : row) {
sbArr[idx].append(elem).append("\t");
}
sbArr[idx].append("]");
}
for (StringBuilder stringBuilder : sbArr) {
System.out.println(stringBuilder);
}
}
}

How to interrupt a method after specific time in Java?

I need to write a simple program that prints prime numbers up to the given number but no longer than 5 seconds.
Is there some kind of timer to use to interrupt a method after a period of time? (but no interruption if printing is shorter than 5 sec).
Thanks in advance.
My code:
public class Primes {
private static boolean checkIfPrime(int x) {
if (x == 2) return true;
if (x % 2 == 0) return false;
int sqrt = (int) Math.sqrt(x) + 1;
for (int i = 3; i < sqrt; i = i + 2) if (x % i == 0) return false;
return true;
}
private static void printPrimesAndOperationTime(int n) {
long start = System.nanoTime();
for (int i = 2; i <= n; i++) if (checkIfPrime(i)) System.out.println(i);
long end = System.nanoTime();
long timeResult = end - start;
System.out.println("Printing time = " + timeResult + " [ns] => "
+ Math.round(timeResult * 100.0 / 1000000) / 100.0 + " [ms]");
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
printPrimesAndOperationTime(n);
}
}
Used Java Concurrency APIs to solve the above problem. please find inline comments for code walk through.
import java.util.Scanner;
import java.util.concurrent.*;
public class TimeoutInterval {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor(); // Start Single thread executor
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
Future future = executor.submit(new Primes(n)); // Find prime no.
try {
future.get(5, TimeUnit.SECONDS); // Set the time out of the prime no. search task
executor.shutdown();
} catch (TimeoutException e) {
executor.shutdown();
System.out.println("Terminated!");
}
executor.shutdownNow();
}
}
class Primes implements Runnable {
private final int number;
Primes(int number) {
this.number = number;
}
#Override
public void run() {
System.out.println("Started..");
printPrimesAndOperationTime(number);
System.out.println("Finished!");
}
private static boolean checkIfPrime(int x) {
if (x == 2) return true;
if (x % 2 == 0) return false;
int sqrt = (int) Math.sqrt(x) + 1;
for (int i = 3; i < sqrt; i = i + 2) if (x % i == 0) return false;
return true;
}
private static void printPrimesAndOperationTime(int n) {
long start = System.nanoTime();
for (int i = 2; i <= n && !Thread.interrupted(); i++) if (checkIfPrime(i)) {
System.out.println(i);
}
long end = System.nanoTime();
long timeResult = end - start;
System.out.println("Printing time = " + timeResult + " [ns] => "
+ Math.round(timeResult * 100.0 / 1000000) / 100.0 + " [ms]");
}
}
Using ExecutorService, you can submit a task with a timeout. On Receiving the TimeoutException, you should call cancel(true) method on the task to interrupt the thread.
From the documentation
... If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.

How to fix NullPointerException in array of multithread app [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
My task: I need to generate BASE (array) of matrix in multiple threads. It can happen that thread won't make matrix at all so I'm try to limit the lifetime of each thread.
My thought: I made volatile array that contains my matrix generation tasks and made ConcurrentHashMap that contains thread and information class (index in task array and time of thread creation)
My problem: I got NullPointerException when I tried to deal with array
Thread information class:
public class ThreadInformation {
private long timeCreated;
private int automatIndex;
public ThreadInformation (long timeCreated, int automatIndex) {
this.timeCreated = timeCreated;
this.automatIndex = automatIndex;
}
public long getTimeCreated() {
return timeCreated;
}
public int getIndex() {
return automatIndex;
}
}
MultiThread class:
public class MultiTaskGenerator {
private final int BASE_SIZE = 10;
private final Automat[] BASE = new Automat[BASE_SIZE];
private static final int THREAD_COUNT = 8;
private final int THREAD_LIVE_TIME_SEC = 10;
private Map<Thread, ThreadInformation> threads = new ConcurrentHashMap<>();
private volatile GeneratorTask[] tasks = new GeneratorTask[THREAD_COUNT];
private int automatReady = 0;
MultiTaskGenerator() {
getThreadResult();
}
private void initThreads() {
for (int i = 0; i < THREAD_COUNT; i++) {
int j = i;
System.out.println("Thread №" + j + " started");
threads.put(new Thread(() -> {
tasks[j] = new GeneratorTask();
}), new ThreadInformation(System.currentTimeMillis(), j));
}
startThreads();
}
private void initNewThread(int index) {
for (int i = 0; i < tasks.length; i++) {
if (i == index) {
threads.put(new Thread(() -> {
tasks[index] = new GeneratorTask();
}), new ThreadInformation(System.currentTimeMillis(), index));
}
}
}
private void startThreads() {
for (Thread thread : threads.keySet()) {
Thread.State state = thread.getState();
if (state == Thread.State.NEW) {
thread.start();
}
}
}
private void getThreadResult() {
initThreads();
for (int i = 0; i < tasks.length; i++) {
System.out.println(tasks[i]);
}
while (automatReady < BASE_SIZE) {
Set mapSet = threads.entrySet();
Iterator iterator = mapSet.iterator();
while (iterator.hasNext()) {
Map.Entry<Thread, ThreadInformation> mapEntry = (Map.Entry)iterator.next();
if (!mapEntry.getKey().isAlive()) {
if (automatReady == BASE_SIZE) continue;
int currentIndex = mapEntry.getValue().getIndex();
BASE[automatReady] = tasks[currentIndex].getAutomat();
System.out.println("Добавлен автомат № " + automatReady);
automatReady++;
System.out.println("Thread №" + mapEntry.getValue().getIndex() + " finished successfully");
iterator.remove();
initNewThread(mapEntry.getValue().getIndex());
startThreads();
System.out.println("Thread №" + mapEntry.getValue().getIndex() + " started");
} else {
if ((System.currentTimeMillis() - mapEntry.getValue().getTimeCreated()) < (THREAD_LIVE_TIME_SEC * 1000)) continue;
int taskIndex = mapEntry.getValue().getIndex();
tasks[taskIndex].stopGeneration(true);
System.out.println("Thread №" + taskIndex + " stoped");
mapEntry.getKey().interrupt();
iterator.remove();
System.out.println("Thread №" + taskIndex + " started");
initNewThread(mapEntry.getValue().getIndex());
startThreads();
}
}
}
threads.clear();
}
public Automat[] getBASE() {
return BASE;
}
}
StackTrace:
Thread №0 started
Thread №1 started
Thread №2 started
Thread №3 started
Thread №4 started
Thread №5 started
Thread №6 started
Thread №7 started
null
null
null
null
null
null
null
null
Exception in thread "main" java.lang.NullPointerException
at ru.stsz.MultiTaskGenerator.getThreadResult(MultiTaskGenerator.java:78)
at ru.stsz.MultiTaskGenerator.<init>(MultiTaskGenerator.java:19)
at ru.stsz.MainApp.main(MainApp.java:6)
Can anyone give me advise how to fix this?
You can Add an assertion each time you need to access your arrays! something like that in the case of emty arrays:
public static void notEmpty(#Nullable Object[] array,String message) {
if (ObjectUtils.isEmpty(array)) {
throw new IllegalArgumentException(message);
}
}

Round Robin Scheduler

I need to implement a "round-robin" scheduler with a job class that I cannot modify. Round-robin scheduler should process the job that has been waiting the longest first, then reset timer to zero. If two jobs have same wait time, lower id is processed first. The job class only gives three values (job id, remaining duration, and priority(which is not needed for this). each job has a start time, so only a couple of jobs may be available during first cycle, few more next cycle, etc. Since the "job array" I am calling is different every time I call it, I'm not sure how to store the wait times.
This is the job class:
public class Jobs{
private int[] stas = new int[0];
private int[] durs = new int[0];
private int[] lefs = new int[0];
private int[] pris = new int[0];
private int[] fins = new int[0];
private int clock;
public Jobs()
{
this("joblist.csv");
}
public Jobs(String filename)
{
BufferedReader fp = null;
String line = "";
String[] b = null;
int[] tmp;
try
{
fp = new BufferedReader(new FileReader(filename));
while((line = fp.readLine()) != null)
{
b = line.split(",");
if(b.length == 3)
{
try
{
int sta = Integer.parseInt(b[0]);
//System.out.println("sta: " + b[0]);
int dur = Integer.parseInt(b[1]);
//System.out.println("dur: " + b[1]);
int pri = Integer.parseInt(b[2]);
//System.out.println("pri: " + b[2]);
stas = app(stas, sta);
//System.out.println("stas: " + Arrays.toString(stas));
durs = app(durs, dur);
//System.out.println("durs: " + Arrays.toString(durs));
lefs = app(lefs, dur);
//System.out.println("lefs: " + Arrays.toString(lefs));
pris = app(pris, pri);
//System.out.println("pris: " + Arrays.toString(pris));
fins = app(fins, -1);
//System.out.println("fins: " + Arrays.toString(fins));
}
catch(NumberFormatException e) {}
}
}
fp.close();
}
catch(FileNotFoundException e) { e.printStackTrace(); }
catch(IOException e) { e.printStackTrace(); }
clock = 0;
}
public boolean done()
{
boolean done = true;
for(int i=0; done && i<lefs.length; i++)
if(lefs[i]>0) done=false;
return done;
}
public int getClock() { return clock; }
public int[][] getJobs()
{
int count = 0;
for(int i=0; i<stas.length; i++)
if(stas[i]<=clock && lefs[i]>0)
count++;
int[][] jobs = new int[count][3];
count = 0;
for(int i=0; i<stas.length; i++)
if(stas[i]<=clock && lefs[i]>0)
{
jobs[count] = new int[]{i, lefs[i], pris[i]};
count++;
}
return jobs;
}
public int cycle() { return cycle(-1); }
public int cycle(int j)
{
if(j>=0 && j<lefs.length && clock>=stas[j] && lefs[j]>0)
{
lefs[j]--;
if(lefs[j] == 0) fins[j] = clock+1;
}
clock++;
return clock;
}
private int[] app(int[] a, int b)
{
int[] tmp = new int[a.length+1];
for(int i=0; i<a.length; i++) tmp[i] = a[i];
tmp[a.length] = b;
return tmp;
}
public String report()
{
String r = "JOB,PRIORITY,START,DURATION,FINISH,DELAY,PRI*DELAY\n";
float dn=0;
float pdn=0;
for(int i=0; i<stas.length; i++)
{
if(fins[i]>=0)
{
int delay = ((fins[i]-stas[i])-durs[i]);
r+= ""+i+","+pris[i]+","+stas[i]+","+durs[i]+","+fins[i]+","+delay+","+(pris[i]*delay)+"\n";
dn+= delay;
pdn+= pris[i]*delay;
}
else
{
int delay = ((clock*10-stas[i])-durs[i]);
r+= ""+i+","+pris[i]+","+stas[i]+","+durs[i]+","+fins[i]+","+delay+","+(pris[i]*delay)+"\n";
dn+= delay;
pdn+= pris[i]*delay;
}
}
if(stas.length>0)
{
r+= "Avg,,,,,"+(dn/stas.length)+","+pdn/stas.length+"\n";
}
return r;
}
public String toString()
{
String r = "There are "+stas.length+" jobs:\n";
for(int i=0; i<stas.length; i++)
{
r+= " JOB "+i+": START="+stas[i]+" DURATION="+durs[i]+" DURATION_LEFT="+lefs[i]+" PRIORITY="+pris[i]+"\n";
}
return r;
}
I don't need full code, just an idea of how to store wait times and cycle the correct job.
While a array based solution 'may' work, I would advocate a more object oriented approach. Create 'Job' class with the desire attributes (id, start_time, wait etc). Using the csv file, create Job objects and hold them in a list. Write a comparator to sort this jobs-list (in this case based on job wait/age would be the factor).
The job executor then has to do the following:
while(jobs exist) {
iterate on the list {
if job is executable // start_time > current sys_time
consume cycles/job for executable jobs
mark completed jobs (optional)
}
remove the completed jobs
}
//\ This loop will add +1 to each job
for(int i = 0; i < jobs.length; i++)
{
waitTime[jobs[i][0]] += 1;
}
int longestWait = 0;//\ This holds value for greatest wait time
int nextJob = 0; //\ This holds value for index of job with greatest wait time
//\ this loop will check for the greatest wait time and and set variables accordingly
for(int i = 0; i < waitTime.length; i++)
{
if(waitTime[i] > longestWait)
{
longestWait = waitTime[i];
nextJob = i;
}
}
//\ this cycles the job with the highest wait time
jobsource.cycle(nextJob);
//\ this resets the wait time for processed job
waitTime[nextJob] = 0;

Need Help intrepretting the results of this program

So, I made a small program to test Multithreading in java and compare the time it takes to scale an array using a while loop and then creating multiple threads and running those threads. I'm unsure about then numbers I'm getting when the program finishes, so I was wondering if I made a boneheaded error at some point and messed something up to get very disparate numbers.
Code below:
import java.util.Scanner;
public class arrayScaling {
public static void main(String[] args) throws InterruptedException {
Scanner input = new Scanner(System.in);
System.out.println("Enter the amount of number you want the program to generate:");
int numOfNumbs = input.nextInt();
int [] arrayForNumbers = new int [numOfNumbs];
int [] newArrayForNumbers = new int [numOfNumbs];
for (int i = 0; i < arrayForNumbers.length; i++) {
arrayForNumbers[i] = (int) ((Math.random() * 25) + 1);
}
long startTime = System.nanoTime();
for (int i = 0; i < arrayForNumbers.length; i++) {
newArrayForNumbers[i] = newArrayForNumbers[i] * 3;
}
long endTime = System.nanoTime();
System.out.println();
long totalExecutionTime = endTime-startTime;
System.out.println("Time it takes execute scaling is " +
totalExecutionTime + " nanoseconds");
System.out.println();
int numOfNumLeftOver = numOfNumbs % 5;
int numOfNumDivided = numOfNumbs / 5;
int [] temp = null;
int [] temp2 = null;
int [] temp3 = null;
int [] temp4 = null;
int [] temp5 = null;
MyThread thread1 = new MyThread (numOfNumbs/5);
MyThread thread2 = new MyThread (numOfNumbs/5);
MyThread thread3 = new MyThread (numOfNumbs/5);
MyThread thread4 = new MyThread (numOfNumbs/5);
MyThread thread5;
if (numOfNumLeftOver != 0) {
numOfNumDivided = numOfNumDivided + numOfNumLeftOver;
thread5 = new MyThread (numOfNumDivided);
}
else {
thread5 = new MyThread (numOfNumbs/5);
}
int tempNum = 0;
for ( int i = 0; i < thread1.getArray().length; i ++) {
temp = thread1.getArray();
temp[tempNum] = arrayForNumbers[tempNum];
tempNum++;
}
for ( int i = 0; i < thread2.getArray().length; i ++) {
temp2 = thread2.getArray();
temp2[i] = arrayForNumbers[tempNum];
tempNum++;
}
for ( int i = 0; i < thread3.getArray().length; i ++) {
temp3 = thread3.getArray();
temp3[i] = arrayForNumbers[tempNum];
tempNum++;
}
for ( int i = 0; i < thread4.getArray().length; i ++) {
temp4 = thread4.getArray();
temp4[i] = arrayForNumbers[tempNum];
tempNum++;
}
for ( int i = 0; i < thread5.getArray().length; i ++) {
temp5 = thread5.getArray();
temp5[i] = arrayForNumbers[tempNum];
tempNum++;
}
thread1.setArray(temp);
thread2.setArray(temp2);
thread3.setArray(temp3);
thread4.setArray(temp4);
thread5.setArray(temp5);
long startTime2 = System.nanoTime();
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
thread1.join();
thread2.join();
thread3.join();
thread4.join();
thread5.join();
long endTime2 = System.nanoTime();
long newTotalExecutionTime = endTime2 - startTime2;
System.out.println("Time it takes execute scaling w/ multiple threads is " +
newTotalExecutionTime + " nanoseconds");
if (newTotalExecutionTime < totalExecutionTime) {
System.out.println("Multithreading was more effective");
}
else if (totalExecutionTime < newTotalExecutionTime) {
System.out.println("The original algorithm was more effective");
}
else if (totalExecutionTime == newTotalExecutionTime) {
System.out.println("Both method worked at the same speed");
}
input.close();
}
}
public class MyThread extends Thread {
private int [] array;
private int [] scaleArray;
public MyThread(int size) {
array = new int [size];
scaleArray = new int [size];
}
public int[] getArray() {
return array;
}
public void setArray(int[] array) {
this.array = array;
}
public int[] getScaleArray() {
return scaleArray;
}
public void setScaleArray(int[] scaleArray) {
this.scaleArray = scaleArray;
}
public void run () {
for (int z = 0; z < array.length; z++){
scaleArray[z] = 3 * array[z];
}
}
}
And the output of this program is:
Enter the amount of number you want the program to generate:
16
Time it takes execute scaling is 893 nanoseconds
Time it takes execute scaling w/ multiple threads is 590345 nanoseconds
The original algorithm was more effective
Your results don't surprise me in the slightest. There's a lot of overhead to creating threads, starting them, waiting for them to finish and so on. Don't forget, 590345ns is still less than a millisecond; but most of that is to do with shuffling threads, not with multiplying the numbers.
If you want to see the threaded part of the program outperform the other part, try generating a whole lot more than 16 numbers.

Categories