Division of a task to threads - multi threading - java

I want to generate pairs from a given large pool of numbers. I am using two for loops and threads. My function getAllPairs() in the code generates apairs with a given array of numbers.
I have an array of length 1000. With one thread, output time is nearly 15 sec. Now I want to use 5-6 threads and reduce this output time.I am stuck at dividing this task equally to five threads.If not threads,how to decrease the output time?
Solution with threads is appreciated since I put a lot of time learning multithreading. I would like to implement it.
import java.util.*;
class Pair {
public int x, y;
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
#Override
public String toString(){
return " ( " + x + " ," + y + " ) " ;
}
}
class selectPairs{
private int[] array;
private List<Pair> totalPairs ;
public selectPairs(int[] arr){
array = arr;
}
//set Method
public void settotalPairs(List<Pair> pieces){
totalPairs = pieces;
}
//get Method
public List<Pair> gettotalPairs(){
return totalPairs;
}
// Method to generate pairs
public List<Pair> getAllPairs() {
List<Pair> pairs = new ArrayList<Pair>();
int total = array.length;
for(int i=0; i < total; i++) {
int num1 = array[i];
for(int j=i+1; j < total; j++) {
int num2 = array[j];
pairs.add(new Pair(num1,num2));
}
}
return pairs;
}
}
// Thread class
class ThreadPairs extends Thread {
private Thread t;
selectPairs SP;
ThreadPairs(selectPairs sp){
SP = sp;
}
public void run() {
synchronized(SP) {
List<Pair> PAIRS = SP.getAllPairs();
SP.settotalPairs(PAIRS);
}
}
}
public class TestThread {
public static void main(String args[]) {
int[] a = new int[1000];
for (int i = 0; i < a.length; i++) {
a[i] = i ;
}
selectPairs ob = new selectPairs(a);
ThreadPairs T = new ThreadPairs( ob );
T.start();
while (true) {
try {
T.join();
break;
}
catch(Exception e){
}
}
List<Pair> Total = new ArrayList<Pair>() ;
List<Pair> Temp1 = ob.gettotalPairs();
Total.addAll(Temp1);
System.out.println(Total);
}
}

A solution with a thread-pool, a task split strategy and it collects all results:
public class SelectPairs {
private static final int NUM_THREADS = 8;
private int[] array;
public SelectPairs(int[] arr) {
array = arr;
}
// A splitting task strategy
public List<Pair> getPartialPairs(int threadIndex, int numThreads) {
List<Pair> pairs = new ArrayList<Pair>();
int total = array.length;
for (int i = threadIndex; i < total; i += numThreads) {
int num1 = array[i];
for (int j = i + 1; j < total; j++) {
int num2 = array[j];
pairs.add(new Pair(num1, num2));
}
}
return pairs;
}
// To use Callables or Runnables are better than extends a Thread.
public static class PartialPairsCall implements Callable<List<Pair>> {
private int thread;
private int totalThreads;
private SelectPairs selectPairs;
public PartialPairsCall(int thread, int totalThreads, SelectPairs selectPairs) {
this.thread = thread;
this.totalThreads = totalThreads;
this.selectPairs = selectPairs;
}
#Override
public List<Pair> call() throws Exception {
return selectPairs.getPartialPairs(thread, totalThreads);
}
}
public static void main(String[] args) throws Exception {
int[] a = new int[1000];
for (int i = 0; i < a.length; i++) {
a[i] = i;
}
SelectPairs sp = new SelectPairs(a);
// Create a thread pool
ExecutorService es = Executors.newFixedThreadPool(NUM_THREADS);
List<Future<List<Pair>>> futures = new ArrayList<>(NUM_THREADS);
// Submit task to every thread:
for (int i = 0; i < NUM_THREADS; i++) {
futures.add(es.submit(new PartialPairsCall(i, NUM_THREADS, sp)));
}
// Collect the results:
List<Pair> result = new ArrayList<>(a.length * (a.length - 1));
for (Future<List<Pair>> future : futures) {
result.addAll(future.get());
}
// Shutdown thread pool
es.shutdown();
System.out.println("result: " + result.size());
}
}

regarding the framework of multithreading, you can implement ThreadPoolExecutor as was suggested in a comment.
Regarding splitting the workload, it seems that the key is splitting the iteration on the array which is achievable if you give the Runnable task a start and end index to iterate over.

Related

How can i get multi thread parallel calculator (factorial sum)

I will input some number to calculates sum of Factorial series,
like if i put 5, output will be 1!+2!+3!+4!+5!, but calculating processing could be heavy so i want to use multiple treads that calculates each factorial.. means thread1 cals 1!, thread2 cals 2!...
i used arrays of threads but can't sync them in propel results. and can't find the way to sum these results.
i wrote codes...
public class Calthread extends Thread{
private int num=1;
public Calthread(int num) {
this.num = num;
}
public void run() {
int dft = 1;
for(int i=1; i<=num; i++) {
dft = dft*i;
}
System.out.println(num + "! result :" + dft);
}
}
this is for 1 thread
for main class
public class calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("input number>>");
int k = scanner.nextInt(); //input 'k'
int sum = 0;
Calthread[] cal = new Calthread[k]; // make threads number of 'k'
for(int i = 0; i<k; i++) {
cal[i] = new Calthread(i+1);
cal[i].start();
}
}
}
how can I Sync them and print the sum of all?
To return value from thread you should use Callable instead of Runnable:
public class Calthread implements Callable<Integer> {
private int num = 1;
public Calthread(int num) {
this.num = num;
}
#Override
public Integer call() {
int dft = 1;
for (int i = 1; i <= num; i++) {
dft = dft * i;
}
return dft;
}
}
And in the main class:
public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("input number>>");
int k = scanner.nextInt(); //input 'k'
int sum = 0;
// Make threads number of 'k'. Here we use List instead of array because there is such contract in ExecutorService
List<Calthread> cal = new ArrayList<>(k);
// Create thread pool with fixed number of threads
ExecutorService service = Executors.newFixedThreadPool(k);
// Add all Callable task in one collection
for (int i = 0; i < k; i++) {
cal.add(new Calthread(i+1));
}
try {
// Invoke all Callable task and get List with results
List<Future<Integer>> results = service.invokeAll(cal);
// Future::get is blocking method. It waits result.
for (Future<Integer> result : results) {
sum += result.get();
}
} catch (InterruptedException | ExecutionException e) {
System.out.println("Something went wrong");
e.printStackTrace();
}
System.out.println("Result: " + sum);
// We need to shutdown our service
service.shutdown();
}
}

Sum of all the elements in an array with ExecutorService pool not working

I am trying to understand ExecutorService and i want to do the sum of all the elements of an array. I did two methods, one that makes the sum serially (just a for loop that sums all the elements) and other concurrently with a pool. My problem is that the total sum from using ExecutorService is off with the serial sum almost all the time, sometimes even just by one.
package sumArregloConc;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class SumaArregloMain {
private final static int cantElem = 1000;
private static ExecutorService tpool = Executors.newCachedThreadPool();
public static void main(String[] args)
{
int[] arreglo = generarArreglo(cantElem); //generate the array with random numbers
System.out.println(sumaSerial(arreglo));
System.out.println(sumaConcurrente(arreglo));
}
public static int sumaSerial(int[] arreglo)
{
int suma = 0;
for(int i =0; i< arreglo.length; i++)
{
suma += arreglo[i];
}
return suma;
}
public static int sumaConcurrente(int[] arreglo)
{
AtomicInteger total = new AtomicInteger(0);
for(int i = 1 ; i < cantElem; i++){
int a = arreglo[i];
Thread thread = new Thread(new Runnable(){
public void run() {
int res = a;
total.addAndGet(res);
return;
}});
tpool.submit(thread);
}
tpool.shutdown(); //wait for everything to finish
return total.get();
}
public static int[] generarArreglo(int cantElem)
{
int[] arreglo = new int[cantElem];
Random rand = new Random();
for(int i = 0; i < cantElem; i++)
{
arreglo[i] = rand.nextInt(10);
}
return arreglo;
}
}
Can someone tell what is wrong?
Found the error. First what Eric said about awaitTermination and Runnable, but the main bug was just that the loop started at i = 1 instead of i = 0, silly mistake.
public static int sumaConcurrente(int[] arreglo)
{
AtomicInteger total = new AtomicInteger(0);
for(int i = 0 ; i < cantElem; i++){
int a = arreglo[i];
tpool.submit(new Runnable(){
public void run() {
total.addAndGet(a);
return;
}
});
}
tpool.shutdown(); //wait for everything to finish
try {
tpool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
}
return total.get();
}

Java Parallel search in a multidimensional array using Threads

The task is to find max and min values in a MxN matrix, and do it "in parallel" using Java Threads.
I was pretty surprised to find out that my parallelSearch() method runs much slower compared to the regularSearch() method. Both of them use the same brute-force algorithm, so even though you can probably solve this problem using a better algorithm, both methods should be on the even playing field.
I'm curious to find out why: is it because creating new Thread objects is a time-expensive task, or is it because I'm doing something totally wrong in my parallelSearch() method?
import java.util.Random;
public class Task {
static int max = -1;
static int min = 99;
static int[][] matrix;
static Random rnd = new Random();
static{
matrix = new int[4][1000];
Task t = new Task();
t.fill(matrix);
}
public static void main(String[] args) throws InterruptedException {
Task t = new Task();
long cur = System.currentTimeMillis();
System.out.println(t.regularSearch(matrix));
System.out.println("regular search took "+(System.currentTimeMillis() - cur)+" millis ");
cur = System.currentTimeMillis();
System.out.println(t.parallelSearch(matrix));
System.out.println("parallel search took "+(System.currentTimeMillis() - cur)+" millis ");
}
void fill(int[][] input){
for (int i = 0; i < input.length; i++) {
for (int i1 = 0; i1 < input[i].length; i1++) {
input[i][i1] = rnd.nextInt(200);
}
}
}
String regularSearch(int[][]input){
StringBuilder result = new StringBuilder();
for (int[] anInput : input) {
for (int anAnInput : anInput) {
if(anAnInput>max){
max = anAnInput;
}
if(anAnInput<min){
min = anAnInput;
}
}
}
String rslt = result.append("max: ").append(max).append(" min: ").append(min).toString();
max = -1;
min = 200; //doing this to have a fair comparison in main()
return rslt;
}
String parallelSearch(int[][] input) throws InterruptedException {
StringBuilder result = new StringBuilder();
for (int i = 0; i < input[0].length; i++) {
int x = i;
Thread t = new Thread(()->{
for (int[] anInput : input) {
if (anInput[x] > max) {
max = anInput[x];
}
if (anInput[x] < min) {
min = anInput[x];
}
}
});
t.start();
}
Thread.sleep(10);
result.append("max: ").append(max).append(" min: ").append(min);
return result.toString();
}
}
EDIT:
As was pointed out in the comments, my parallelSearch() was creating way more Threads than necessary, and I've rewritten it to better suit my task. This one actually runs faster than the regular one on big sizes. I've tested it against a 4x500000 matrix with random.nextInt(100000) bound and it runs as fast or even up to 10 seconds faster then the regularSearch()
String parallelSearch(int[][] input) throws InterruptedException {
StringBuilder result = new StringBuilder();
for (int i = 0; i < input.length; i++) {
int x = i;
Thread t = new Thread(()->{
for(int num:input[x]){
if(num>max){
max = num;
}
if(num<min){
min = num;
}
}
});
t.start();
}
Thread.sleep(10);
result.append("max: ").append(max).append(" min: ").append(min);
return result.toString();
}

Merge LinkedList and Sort using Multithreading

I am building a project in which I want to generate several linkedlist in parallel, then merge them and at last want to sort it using multithreading. I have created linkedlists in parallel. Actually I am not sure it is generated sequentially or parallelly. Can anyone help me in solving the problem.
My code is:
public class ParallelMaximizer {
int numThreads;
Random r = new Random();
int Low = 10;
int High = 100;
int numElements = 10;
static ParallelMaximizerWorker[] workers;
public ParallelMaximizer(int numThreads) {
workers = new ParallelMaximizerWorker[numThreads];
}
public static void main(String[] args) {
int numThreads = 4;
ParallelMaximizer maximizer = new ParallelMaximizer(numThreads);
LinkedList<Integer> list = new LinkedList<Integer>();
try {
System.out.println("Maximum Number -> " + maximizer.max(list));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public int max(LinkedList<Integer> list) throws InterruptedException {
int max = Integer.MIN_VALUE;
for (int j=0; j<workers.length; j++){
for (int i=0; i<numElements; i++){
int numValues = r.nextInt(High-Low) + Low;
list.add(numValues);
}
System.out.println("LinkedList -> " + list);
for (int i=0; i < workers.length; i++) {
workers[i] = new ParallelMaximizerWorker(list);
workers[i].start();
}
for (int i=0; i<workers.length; i++){
try {
workers[i].join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
list = new LinkedList<>();
}
for(ParallelMaximizerWorker pmw : workers){
max = Math.max(max, pmw.partialMax);
}
return max;
}
}
Other class is:
public class ParallelMaximizerWorker extends Thread {
protected LinkedList<Integer> list;
protected int partialMax = Integer.MIN_VALUE; // initialize to lowest value
public ParallelMaximizerWorker(LinkedList<Integer> list) {
this.list = list;
}
public void run() {
while (true) {
int number;
synchronized(list) {
if (list.isEmpty())
return; // list is empty
number = list.remove();
}
partialMax = Math.max(number, partialMax);
}
}
public int getPartialMax() {
return partialMax;
}
}

Mean, Median, and Mode - Newb - Java

We had a lab in Comsci I couldn't figure out. I did a lot of research on this site and others for help but they were over my head. What threw me off were the arrays. Anyway, thanks in advance. I already got my grade, just want to know how to do this :D
PS: I got mean, I just couldn't find the even numbered median and by mode I just gave up.
import java.util.Arrays;
import java.util.Random;
public class TextLab06st
{
public static void main(String args[])
{
System.out.println("\nTextLab06\n");
System.out.print("Enter the quantity of random numbers ===>> ");
int listSize = Expo.enterInt();
System.out.println();
Statistics intList = new Statistics(listSize);
intList.randomize();
intList.computeMean();
intList.computeMedian();
intList.computeMode();
intList.displayStats();
System.out.println();
}
}
class Statistics
{
private int list[]; // the actual array of integers
private int size; // user-entered number of integers in the array
private double mean;
private double median;
private int mode;
public Statistics(int s)
{
size = s;
list = new int[size];
mean = median = mode = 0;
}
public void randomize()
{
Random rand = new Random(12345);
for (int k = 0; k < size; k++)
list[k] = rand.nextInt(31) + 1; // range of 1..31
}
public void computeMean()
{
double total=0;
for (int f = 0; f < size; f++)
{
total = total + list[f];
}
mean = total / size;
}
public void computeMedian()
{
int total2 = 0;
Arrays.sort(list);
if (size / 2 == 1)
{
// total2 =
}
else
{
total2 = size / 2;
median = list[total2];
}
}
public void computeMode()
{
// precondition: The list array has exactly 1 mode.
}
public void displayStats()
{
System.out.println(Arrays.toString(list));
System.out.println();
System.out.println("Mean: " + mean);
System.out.println("Median: " + median);
System.out.println("Mode: " + mode);
}
}
Here are two implementations for your median() and mode() methods:
public void computeMedian() {
Arrays.sort(list);
if ( (list.size & 1) == 0 ) {
// even: take the average of the two middle elements
median = (list[(size/2)-1] + list[(size/2)]) / 2;
} else {
// odd: take the middle element
median = list[size/2];
}
}
public void computeMode() {
// precondition: The list array has exactly 1 mode.
Map<Integer, Integer> values = new HashMap<Integer, Integer>();
for (int i=0; i < list.size; ++i) {
if (values.get(list[i]) == null) {
values.put(list[i], 1);
} else {
values.put(list[i], values.get(list[i])+1);
}
}
int greatestTotal = 0;
// iterate over the Map and find element with greatest occurrence
Iterator it = values.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
if (pair.getValue() > greatestTotal) {
mode = pair.getKey();
greatestTotal = pair.getValue();
}
it.remove();
}
}

Categories

Resources