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;
}
}
Related
The program's aim is to simulate that multiple users add a number to the buffer from 0 to n. Then print the sum of numbers in the buffer. When I run the program, it seems that the threads never end. However, the thread will finish when I run the program in debug mode of Idea and step line by line. Also, I do not exactly know where I need to use my semaphore method P() and V() for mutual exclusion.
Version: JDK 8. I cannot use semaphore in the library.
Main.java
Buffer b = new Buffer(bufferSize);
ArrayList<user> us = new ArrayList<>();
for(int i = 0; i < num_users; i++) us.add(new user(i, elements, b));
ArrayList<Thread> th = new ArrayList<>();
for(int i = 0; i < num_users; i++)
{
th.add(new Thread(us.get(i)));
th.get(i).start();
}
user.java
public class user implements Runnable
{
private int id;
private int num_elements;
private semaphore mutex = new semaphore(1 );
public static Buffer buf;
public user(int i, int el, Buffer b)
{id = i; num_elements = el; buf = b;}
public void add_elements()
{//Add element to buffer, element value iterates from 0, 1, 2 .... num_elements
mutex.P();
int n = 0;
while (num_elements > 0)
{
buf.add(new Integer(n));
n++;
num_elements--;
}
mutex.V();
}
public void run()
{
add_elements();
}
}
Buffer.java
public class Buffer
{
private LinkedList<Object> buf_list;
private int elements; //Number of elements currently on the queue
private int buf_size; //Maximum number of elements allowed on queue
private semaphore mutex = new semaphore(1);
public Buffer(int n) //Queue creation, with n indicating the maximum capacity
{
buf_list = new LinkedList<Object>();
elements = 0;
buf_size = n;
}
public void add(Integer n)
{
mutex.P();
buf_list.add(n);
elements++;
mutex.V();
}
public void finalSummation()
{
if (elements == buf_size)
{
mutex.P();
int sum = 0;
for (Object n : buf_list)
sum += ((Integer)n).intValue();
mutex.V();
System.out.println("Count total: " + sum);
}
}
}
semaphore.java
public class semaphore
{
private int count = 0;
public semaphore(int init_count)
{
count = init_count;
}
public synchronized void P()
{
count -= 1;
while (count < 0)
{
try {
wait();
} catch (InterruptedException e) {
System.out.println("Error");
System.exit(-1);
}
}
}
public synchronized void V()
{
count += 1;
notifyAll();
}
}
I expect it will print the sum of buffer numbers, but the thread may not finish.
There are a few things that stand out as issues here.
1) your code is never calling the finalSummation method. So the "printing" of the result will never happen.
2) Buffer and each user are all creating their own semaphores. If you are attempting to allow multiple threads to update Buffer without colliding then you need to share the same semaphore. Remove the semaphore and the usage of it from the user class. Just let the Buffer instance control only one update at a time with its semaphore.
3) You don't need to check the semaphore in the finalSummation method. Presumably, all threads are done at that point. And to enforce that ...
4) Put code like this at the end of main
for(int i = 0; i < num_users; i++) {
th.get(i).join();
}
b.finalSummation();
5) A semaphore should manage a number of permits. Your semaphore is managing the number of instances waiting - that is a pretty much an irrelevant number for a semaphore. Change your P() and V() to acquire() and release() to be consistent with the pattern.
public static class semaphore {
private int permits = 0;
public semaphore(int permits) {
this.permits = permits;
}
public synchronized void acquire() {
while (permits < 1) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Error");
System.exit(-1);
}
}
permits--;
}
public void release() {
synchronized (this) {
permits += 1;
notifyAll();
}
}
}
I have put it together using the above answer if that helps. Please select above answer as the right answer.
import java.util.ArrayList;
import java.util.LinkedList;
public class Main {
// assumed values
private static final int bufferSize = 5;
private static final int num_users = 10;
private static final int elements = 5;
public static void main(String[] args) {
Buffer b = new Buffer(bufferSize);
ArrayList<User> us = new ArrayList<>();
for(int i = 0; i < num_users; i++) us.add(new User(i, elements, b));
ArrayList<Thread> th = new ArrayList<>();
for(int i = 0; i < num_users; i++)
{
th.add(new Thread(us.get(i)));
th.get(i).start();
}
for(int i = 0; i < num_users; i++) {
try {
th.get(i).join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
b.finalSummation();
System.out.println("Exiting");
}
}
class User implements Runnable
{
private int id;
private int num_elements;
public static Buffer buf;
public User(int i, int el, Buffer b)
{id = i; num_elements = el; buf = b;}
public void add_elements()
{//Add element to buffer, element value iterates from 0, 1, 2 .... num_elements
int n = 0;
while (num_elements > 0)
{
buf.add(new Integer(n));
n++;
num_elements--;
}
}
public void run()
{
add_elements();
}
}
class Buffer
{
private LinkedList<Object> buf_list;
private int elements; //Number of elements currently on the queue
private int buf_size; //Maximum number of elements allowed on queue
private Semaphore mutex ;
public Buffer(int n) //Queue creation, with n indicating the maximum capacity
{
buf_list = new LinkedList<Object>();
elements = 0;
buf_size = n;
mutex = new Semaphore(buf_size);
}
public synchronized void add(Integer n)
{
mutex.acquire();
buf_list.add(n);
elements++;
mutex.release();
}
public void finalSummation()
{
int sum = 0;
System.out.println(buf_list);
for (Object n : buf_list)
sum += ((Integer)n).intValue();
System.out.println("Count total: " + sum);
}
}
class Semaphore {
private int permits = 0;
public Semaphore(int permits) {
this.permits = permits;
}
public synchronized void acquire() {
while (permits < 1) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Error");
System.exit(-1);
}
}
permits--;
}
public void release() {
synchronized (this) {
permits += 1;
notifyAll();
}
}
}
public double[] call() throws Exception {
int [] zero = {0,0};
double [] return_to_thread = { };
List<Integer> MyList = new ArrayList<Integer>();
for(int i = 0; i < N_W; i++) {
if(MyList.size() == n) {
N++;
}
MyList.clear();
int [] initial_point = {x,y};
for(int istep = 0; istep < n; istep++) {
randomWalk(initial_point);
if(!MyList.contains(computeHashCode(initial_point)) && !MyList.contains(computeHashCode(zero))) {
MyList.add(computeHashCode(initial_point));
} else {
break;
}
}
if(MyList.size() == n) {
end_to_end_dis_sq += Math.pow(initial_point[0], 2) + Math.pow(initial_point[1], 2);
}
}
return_to_thread[0] += N;
return_to_thread[1] += S;
// System.out.print(return_to_thread);
Thread.sleep(3000);
return return_to_thread;
}
The code above is the call() function that will return an array with double as the type.
public static void main(String [] args) {
ExecutorService service = Executors.newFixedThreadPool(1);
List<Future<double[]>> list = new ArrayList<Future<double[]>>();
Callable<double[]> callable = new Callable_class_1a();
for(int i = 0; i < 1; i++) {
//Submit the task for execution.
Future<double[]> future = service.submit(callable);
list.add(future);
}
for(Future<double[]> futu : list) {
try {
System.out.print(Arrays.toString(futu.get()));
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
service.shutdown();
}
}
}
And the code above is the main function that supposed to print out the value that I get from call() function. I ran this on Eclipse, and when I clicked run nothing happened.
I wonder what happened, and how do I solve this?
I can clarify any part that confused you.
This is my first every question on Stackoverflow, hope everyone treat me nicely :)
I have a merge-sort algorithm that splits an unsorted array into multiple buckets as specified in the main method. I am required to have multiple threads where each thread does work on a single bucket to sort the numbers in that bucket and then merge the results together. How do i go about it given the following piece of code. i have done so...managed to create threads proportional to the number of array buckets...but now how do i assign the buckets to each thread worker...i have edited the code in the posting please.
public class Test{
public static void main(String[] args) {
int[] numsToSort = {1,5,3,7,10,4,6,11,2,8,9,12,16,14,17,13,19,20};
int[] sorted = bucketSort(numsToSort,3);
System.out.print("Sorted: ");
for (int i = 0; i < sorted.length; i++) {
System.out.print(sorted[i] + " ");
}
}
public static int[] bucketSort(int[] numbers, int bucketCount) {
if (numbers.length <= 1)
return numbers;
int maxVal = numbers[0];
int minVal = numbers[0];
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] > maxVal)
maxVal = numbers[i];
if (numbers[i] < minVal)
minVal = numbers[i];
}
double interval = ((double) (maxVal - minVal + 1)) / bucketCount; // range of bucket
ArrayList<Integer> buckets[] = new ArrayList[bucketCount];
for (int i = 0; i < bucketCount; i++) // initialize buckets (initially empty)
buckets[i] = new ArrayList<Integer>();
for (int i = 0; i < numbers.length; i++) // distribute numbers to buckets
buckets[(int) ((numbers[i] - minVal) / interval)].add(numbers[i]);
int k = 0;
//=======================================
for (int i = 0; i < buckets.length; i++) {
ExecutorService executor = Executors.newFixedThreadPool(3);
//System.out.println("buckets " + i + " " + buckets[i]);
//submitting tasks
//for (int i = 0; i <5; i++) {
executor.submit(new App(i));
Collections.sort(buckets[i]); // calls Java's built-in merge sort(as a kind of “helper” sort)
for (int j = 0; j < buckets[i].size(); j++) { // update array with the bucket content
numbers[k] = buckets[i].get(j);
k++;
}
//}
executor.shutdown();
System.out.println("All tasks submitted...");
try {
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("All tasks completed...");
}
return numbers;
}
}
class App implements Runnable{
private int id;
public App(int id){
this.id = id;
}
#Override
public void run() {
System.out.println("starting..." + id);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("completed..." + id);
}
}
Here is an SSCCE, while the approach is a bit different than yours (Java 8) it accomplishes what I believe you question described.
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class ThreadSorter
{
private static Random random = new Random();
public static void main(String[] args)
{
List<Integer> numsToSort = random.ints(0, 50).limit(60L).boxed()
.collect(Collectors.toList());
ThreadSorter testClass = new ThreadSorter();
List<Integer> sorted = testClass.bucketSort(numsToSort, 4);
System.out.print("Sorted: ");
sorted.stream().forEach(i -> System.out.print(i + " "));
}
public List<Integer> bucketSort(List<Integer> numbers, int bucketCount)
{
if (numbers.size() <= 1)
return numbers;
Queue<ArrayList<Integer>> buckets = new LinkedList<ArrayList<Integer>>();
// create buckets
buckets.addAll(IntStream.range(0, bucketCount)
.mapToObj(i -> new ArrayList<Integer>()).collect(Collectors.toList()));
// iterate numbers adding to current bucket (revolving queue additions)
for (int i = 0; i < numbers.size(); i++)
{
ArrayList<Integer> currentBucket = buckets.poll();
currentBucket.add(numbers.get(i));
buckets.offer(currentBucket);
}
// LinkedList is a queue and a list :)
List<ArrayList<Integer>> bucketList = (List<ArrayList<Integer>>) buckets;
for (int i = 0; i < bucketList.size(); i++)
{
System.out.println("buckets " + i + ": " + bucketList.get(i));
}
// create Threads for each bucket
List<Thread> threads = bucketList.stream()
.map(e -> new Thread(new BucketSorter(e))).collect(Collectors.toList());
// start threads
threads.stream().forEach(Thread::start);
// join threads (make sure all are complete before continuing)
for (Thread t : threads)
{
try
{
t.join();
}
catch (InterruptedException e1)
{}
}
// debug statement shoing individual buckets are sorted
for (int i = 0; i < bucketList.size(); i++)
{
System.out.println("sorted buckets " + i + ": " + bucketList.get(i));
}
// recombine the individual buckets and sort them
List<Integer> newlist = (bucketList.stream().flatMap(e -> e.stream())
.collect(Collectors.toList()));
Collections.sort(newlist);
return newlist;
}
}
/**
* Debug statements show the start order of the threads is not necessarily the
* finish order.
*
*/
public class BucketSorter
implements Runnable
{
List<Integer> bucket;
public BucketSorter(List<Integer> bucket)
{
this.bucket = bucket;
}
#Override
public void run()
{
System.out.println(
"Thread Launched: " + Thread.currentThread().getName() + ".");
try
{
Thread.sleep(random.longs(400, 2000).findFirst().orElse(200L));
}
catch (InterruptedException e)
{}
System.out.println(
"Thread Done Sleeping: " + Thread.currentThread().getName() + ".");
Collections.sort(bucket);
System.out.println(
"Thread Finished: " + Thread.currentThread().getName() + ".");
}
}
I have a problem with implementation of merge sort in java. I am looking for the error almost week unfortunately without result. ArrayList at the entrance is the same as the output.
import java.util.ArrayList;
import java.util.Scanner;
public class MergeSort
{
private ArrayList<Integer> basicArrayList = new ArrayList<Integer>();
ArrayList<Integer> arrayListA = new ArrayList<Integer>();
ArrayList<Integer> arrayListB = new ArrayList<Integer>();
Scanner input = new Scanner(System.in);
private int firstIndexOfArrayList = 0;
private int lastIndexOfArrayListA;
private int lastIndexOfArrayListB;
public void Scal(ArrayList<Integer> basicArrayList, int p, int q, int r) {
this.firstIndexOfArrayList = p;
this.lastIndexOfArrayListA = q;
this.lastIndexOfArrayListB = r;
int numberOfElementsArrayListA = lastIndexOfArrayListA
- firstIndexOfArrayList + 1;
int numberOfElementsArrayListB = lastIndexOfArrayListB
- lastIndexOfArrayListA;
for (int i = 0; i < numberOfElementsArrayListA; i++) {
arrayListA.set(i, basicArrayList.get(firstIndexOfArrayList + i));
}
for (int j = 0; j < numberOfElementsArrayListB; j++) {
arrayListB.set(j, basicArrayList.get(lastIndexOfArrayListA + j));
}
arrayListA.add(Integer.MAX_VALUE);
arrayListB.add(Integer.MAX_VALUE);
int i = 0;
int j = 0;
for (int k = firstIndexOfArrayList; k <= lastIndexOfArrayListB; k++) {
if (arrayListA.get(i) <= arrayListB.get(j)) {
basicArrayList.set(k, arrayListA.get(i));
i = i + 1;
} else {
basicArrayList.set(k, arrayListB.get(j));
j = j + 1;
}
}
}
public void MergeSort(ArrayList basicArrayList, int p, int r) {
this.firstIndexOfArrayList = p;
this.lastIndexOfArrayListB = r;
if (firstIndexOfArrayList < lastIndexOfArrayListB) {
int lastIndexOfArrayListA = (firstIndexOfArrayList + lastIndexOfArrayListB) / 2;
MergeSort(basicArrayList, firstIndexOfArrayList,
lastIndexOfArrayListA);
MergeSort(basicArrayList, lastIndexOfArrayListA + 1,
lastIndexOfArrayListB);
Scal(basicArrayList, firstIndexOfArrayList,
lastIndexOfArrayListA,
lastIndexOfArrayListB);
}
}
public void setSize() {
System.out.println("Enter the number of elements to sort: ");
this.lastIndexOfArrayListB = input.nextInt();
}
public int getSize() {
return lastIndexOfArrayListB;
}
public void setData() {
System.out.println("Enter the numbers: ");
for (int i = 0; i < lastIndexOfArrayListB; i++) {
int number;
number = input.nextInt();
basicArrayList.add(number);
}
}
public void getTable() {
System.out.println(basicArrayList.toString());
}
public static void main(String[] args) {
MergeSort output = new MergeSort();
output.setSize();
output.setData();
output.MergeSort(output.basicArrayList,
output.firstIndexOfArrayList, (output.getSize() - 1));
output.getTable();
}
}
In terms of fixing your code I had a crack at it and as far as I can tell this seems to work. To do this a lot of your code had to be changed but it does now sort all Integers properly
import java.util.ArrayList;
import java.util.Scanner;
public class MergeSort
{
private ArrayList<Integer> basicArrayList = new ArrayList<Integer>();
Scanner input = new Scanner(System.in);
private int numbersToSort;
public void doMergeSort(int firstIndexOfArrayList,int lastIndexOfArrayListB, ArrayList<Integer> arrayList)
{
if(firstIndexOfArrayList<lastIndexOfArrayListB && (lastIndexOfArrayListB-firstIndexOfArrayList)>=1)
{
int mid = (lastIndexOfArrayListB + firstIndexOfArrayList)/2;
doMergeSort(firstIndexOfArrayList, mid, arrayList);
doMergeSort(mid+1, lastIndexOfArrayListB, arrayList);
Scal(firstIndexOfArrayList,mid,lastIndexOfArrayListB, arrayList);
}
}
public void Scal(int firstIndexOfArrayList,int lastIndexOfArrayListA,int lastIndexOfArrayListB, ArrayList<Integer> arrayList)
{
ArrayList<Integer> mergedSortedArray = new ArrayList<Integer>();
int leftIndex = firstIndexOfArrayList;
int rightIndex = lastIndexOfArrayListA+1;
while(leftIndex<=lastIndexOfArrayListA && rightIndex<=lastIndexOfArrayListB)
{
if(arrayList.get(leftIndex)<=arrayList.get(rightIndex))
{
mergedSortedArray.add(arrayList.get(leftIndex));
leftIndex++;
}
else
{
mergedSortedArray.add(arrayList.get(rightIndex));
rightIndex++;
}
}
while(leftIndex<=lastIndexOfArrayListA)
{
mergedSortedArray.add(arrayList.get(leftIndex));
leftIndex++;
}
while(rightIndex<=lastIndexOfArrayListB)
{
mergedSortedArray.add(arrayList.get(rightIndex));
rightIndex++;
}
int i = 0;
int j = firstIndexOfArrayList;
while(i<mergedSortedArray.size())
{
arrayList.set(j, mergedSortedArray.get(i++));
j++;
}
}
public void setSize()
{
System.out.println("Enter the number of elements to sort: ");
this.numbersToSort = input.nextInt();
}
public int getSize()
{
return numbersToSort;
}
public void setData()
{
System.out.println("Enter the numbers: ");
for (int i = 0; i < numbersToSort; i++)
{
int number;
number = input.nextInt();
basicArrayList.add(number);
}
}
public void getTable()
{
System.out.println(basicArrayList.toString());
}
public void runSort(ArrayList<Integer> arrayList)
{
doMergeSort(0, this.numbersToSort-1, arrayList);
}
public static void main(String[] args)
{
MergeSort output = new MergeSort();
output.setSize();
output.setData();
output.runSort(output.basicArrayList);
output.getTable();
}
}
Try this code. The following code takes an ArrayList input and outputs an ArrayList as well so it still works along the same basis of your code. The actual sort is handled in a different class MergeSort and is passes into ForMergeSort. Hope this helps
MergeSort.java
public class MergeSort
{
private int[] array;
private int[] tempMergArr;
private int length;
public void sort(int[] inputArr)
{
}
public int[] getSortedArray(int[] inputArr)
{
this.array = inputArr;
this.length = inputArr.length;
this.tempMergArr = new int[length];
doMergeSort(0, length - 1);
for(int i=0;i<length;i++)
{
int correctNumber = i+1;
System.out.println("Value "+correctNumber+" of the sorted array which was sorted via the Merge Sort is: "+inputArr[i]);
}
return inputArr;
}
private void doMergeSort(int lowerIndex, int higherIndex)
{
if (lowerIndex < higherIndex)
{
int middle = lowerIndex + (higherIndex - lowerIndex) / 2;
doMergeSort(lowerIndex, middle);
doMergeSort(middle + 1, higherIndex);
mergeParts(lowerIndex, middle, higherIndex);
}
}
private void mergeParts(int lowerIndex, int middle, int higherIndex)
{
for (int i = lowerIndex; i <= higherIndex; i++)
{
tempMergArr[i] = array[i];
}
int i = lowerIndex;
int j = middle + 1;
int k = lowerIndex;
while (i <= middle && j <= higherIndex)
{
if (tempMergArr[i] <= tempMergArr[j])
{
array[k] = tempMergArr[i];
i++;
}
else
{
array[k] = tempMergArr[j];
j++;
}
k++;
}
while (i <= middle)
{
array[k] = tempMergArr[i];
k++;
i++;
}
}
}
ForMergeSort.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class ForMergeSort
{
ArrayList<Integer> arrayList = new ArrayList<Integer>();
ArrayList<Integer> sortedArrayList = new ArrayList<Integer>();
MergeSort mS = new MergeSort();
public void buildArrayList()
{
Scanner input = new Scanner(System.in);
System.out.println("Enter the number of elements to sort: ");
int toSort = input.nextInt();
System.out.println("Enter the numbers: ");
for(int i =0; i<toSort; i++)
{
int number = input.nextInt();
arrayList.add(number);
}
}
public void runMergeSort(ArrayList<Integer> arrayList)
{
int[] arrayOfValues = new int[arrayList.size()];
int i = 0;
for(int a:arrayList)
{
arrayOfValues[i] = a;
i++;
}
MergeSort mS = new MergeSort();
for(int intOfArray:mS.getSortedArray(arrayOfValues))
{
sortedArrayList.add(intOfArray);
}
System.out.println(sortedArrayList.toString());
}
public static void main(String[] args)
{
ForMergeSort fMS = new ForMergeSort();
fMS.buildArrayList();
fMS.runMergeSort(fMS.arrayList);
}
}
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.