I am trying to solve multiple optimization instances in parallel and created a toy example. When I solve each instance with a single thread, it works fine. When I start increasing the number of threads, I receive out of memory exception for some instances. I was wondering if someone could give me a hint on how to fix this issue.
I tried my best to make the example as simple as possible.
import java.util.Iterator;
import java.util.Vector;
public class ConcurrentExample {
public static int fixed;
public static int nbWarehouses;
public static int nbStores;
public static void main(String[] args) throws IloException, InterruptedException {
int nProblems = 20;
final Vector<Integer> v = new Vector<Integer>();
for (int i = 1; i <= nProblems; ++i) v.add(i);
final Iterator<Integer> it = v.iterator();
int nTHREADS = 2; //numofCores
Thread[] threads = new Thread[nTHREADS ];
for (int t = 0; t < nTHREADS ; ++t) {
threads[t] = new Thread(new Runnable() {
public void run() {
while (true) {
int i;
synchronized (it) {
if ( !it.hasNext() ) return;
i = it.next();
}
fixed = 400 + i;
nbWarehouses = 400 ;
nbStores = 800 + i;
int[] capacity = new int[nbWarehouses];
int[][] supplyCost= new int[nbStores][nbWarehouses];
for(int w=0; w< nbWarehouses ; w++) {
capacity[w] = (nbStores/ nbWarehouses) + (w % ( nbStores/ nbWarehouses));
for(int s=0; s< nbStores ; s++) {
supplyCost[s][w] = 1 + ( ( s + 10 * w) % 100 );
}
}
}
}
}
);
}
for (int t = 0; t < nTHREADS; ++t) { threads[t].start(); }
for (int t = 0; t < nTHREADS; ++t) { threads[t].join(); }
}
}
When I use two threads, I receive the following error:
Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: 801
at concurrent$1.run(concurrent.java:36)
at java.lang.Thread.run(Thread.java:748)
When I set NTHREADS=4, then I receive the following error.
Exception in thread "Thread-1" Exception in thread "Thread-0" Exception in thread "Thread-2" java.lang.ArrayIndexOutOfBoundsException: 802
at concurrent$1.run(concurrent.java:36)
at java.lang.Thread.run(Thread.java:748)
java.lang.ArrayIndexOutOfBoundsException: 801
at concurrent$1.run(concurrent.java:36)
at java.lang.Thread.run(Thread.java:748)
java.lang.ArrayIndexOutOfBoundsException: 803
at concurrent$1.run(concurrent.java:36)
at java.lang.Thread.run(Thread.java:748)
EDIT: One very important thing is that I have to keep the variables as globally defined. This is just a toy example. In the real model, I have static variables which are accessed by multiple methods during an iterative solution approach.
When two threads started, "nbStores" may be incremented, through which iteration done on line 36 may get ArrayIndexOutOfException.
First thread starts with
int[][] supplyCost= new int[nbStores][nbWarehouses];//nbStores=801
Once second thread started, nbStores will become 802, which may affect the loop to run till s=801.
for(int s=0; s< nbStores ; s++)
Why use so many static field? There will be no problem if you use local variables:
import java.util.Iterator;
import java.util.Vector;
public class ConcurrentExample {
public static void main(String[] args) throws InterruptedException {
int nProblems = 20;
final Vector<Integer> v = new Vector<Integer>();
for (int i = 1; i <= nProblems; ++i) v.add(i);
final Iterator<Integer> it = v.iterator();
int nTHREADS = 2; //numofCores
Thread[] threads = new Thread[nTHREADS];
for (int t = 0; t < nTHREADS ; ++t) {
threads[t] = new Thread(new Runnable() {
public void run() {
while (true) {
int i;
synchronized (it) {
if ( !it.hasNext() ) return;
i = it.next();
}
int nbWarehouses = 400 ;
int nbStores = 800 + i;
int[] capacity = new int[nbWarehouses];
int[][] supplyCost= new int[nbStores][nbWarehouses];
for(int w=0; w< nbWarehouses ; w++) {
capacity[w] = (nbStores/ nbWarehouses) + (w % ( nbStores/ nbWarehouses));
for(int s=0; s< nbStores ; s++) {
supplyCost[s][w] = 1 + ( ( s + 10 * w) % 100 );
}
}
}
}
}
);
}
for (int t = 0; t < nTHREADS; ++t) { threads[t].start(); }
for (int t = 0; t < nTHREADS; ++t) { threads[t].join(); }
}
}
I'm trying to learn multi-threading but cant get the hang of it. I've an example here.
The idea is to use two threads to sort the two arrays a and b and use another thread to merge the sorted arrays to array c.
This is my code. I tried it with threads didnt work, so i've put up the code without the threads
public class Main {
public static void main(String[] args){
Random r = new Random(System.currentTimeMillis());
int n = r.nextInt(101) + 50;
int[] a = new int[n];
for(int i = 0; i < n; i++)
a[i] = r.nextInt(100);
n = r.nextInt(101) + 50;
int[] b = new int[n];
for(int i = 0; i < n; i++)
b[i] = r.nextInt(100);
SortThread t1 = new SortThread(a);
SortThread t2 = new SortThread(b);
MergeThread m = new MergeThread(t1.get(),t2.get());
System.out.println(Arrays.toString(m.get()));
}
}
public class SortThread {
int[] x;
public SortThread(int[] x){
this.x = x;
run();
}
public void run(){
sort(x);
}
private void sort(int[] x){
for(int i = 0; i < x.length ; i++){
int indexOfSmallest = findIndexOfSmallest(x, i);
int t = x[i];
x[i] = x[indexOfSmallest];
x[indexOfSmallest] = t;
}
}
private int findIndexOfSmallest(int[] a, int from){
int indexOfSmallest = from;
for(int i = from; i < a.length; i++)
if(a[i] < a[indexOfSmallest])
indexOfSmallest = i;
return indexOfSmallest;
}
public int[] get(){
return x;
}
}
public class MergeThread {
int[] a;
int[] b;
int[] c;
public MergeThread(int[] a, int[] b){
this.a = a;
this.b = b;
c = new int[a.length + b.length];
run();
}
public void run(){
merge();
}
private void merge(){
int aIndex = 0, bIndex = 0, cIndex = 0;
while(aIndex < a.length && bIndex < b.length)
if(a[aIndex] < b[bIndex])
c[cIndex++] = a[aIndex++];
else
c[cIndex++] = b[bIndex++];
while(aIndex < a.length)
c[cIndex++] = a[aIndex++];
while(bIndex < b.length)
c[cIndex++] = b[bIndex++];
}
public int[] get(){
return c;
}
}
A thread should implement the interface runnable and should override the method run.
Please Read Complete reference JAVA, it has many good examples.
Like i mentioned even if you extend thread/implement runnable, the thread you are creating has to be started by a start method, which should be overrided again.
public void start () { System.out.println("Starting " + threadName ); if (t == null) { t = new Thread (this, threadName); t.start (); } }
After this new can create a new instance of your thread and start it . In your case It should be
t1.start()
t2.start()
m.start()
I'm trying to create a Java program with threads for matrix multiplication. This is the source code:
import java.util.Random;
public class MatrixTest {
//Creating the matrix
static int[][] mat = new int[3][3];
static int[][] mat2 = new int[3][3];
static int[][] result = new int[3][3];
public static void main(String[] args) {
//Creating the object of random class
Random rand = new Random();
//Filling first matrix with random values
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat[i].length; j++) {
mat[i][j] = rand.nextInt(10);
}
}
//Filling second matrix with random values
for (int i = 0; i < mat2.length; i++) {
for (int j = 0; j < mat2[i].length; j++) {
mat2[i][j] = rand.nextInt(10);
}
}
try {
//Object of multiply Class
Multiply multiply = new Multiply(3, 3);
//Threads
MatrixMultiplier thread1 = new MatrixMultiplier(multiply);
MatrixMultiplier thread2 = new MatrixMultiplier(multiply);
MatrixMultiplier thread3 = new MatrixMultiplier(multiply);
//Implementing threads
Thread th1 = new Thread(thread1);
Thread th2 = new Thread(thread2);
Thread th3 = new Thread(thread3);
//Starting threads
th1.start();
th2.start();
th3.start();
th1.join();
th2.join();
th3.join();
} catch (Exception e) {
e.printStackTrace();
}
//Printing the result
System.out.println("\n\nResult:");
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[i].length; j++) {
System.out.print(result[i][j] + " ");
}
System.out.println();
}
}//End main
}//End Class
//Multiply Class
class Multiply extends MatrixTest {
private int i;
private int j;
private int chance;
public Multiply(int i, int j) {
this.i = i;
this.j = j;
chance = 0;
}
//Matrix Multiplication Function
public synchronized void multiplyMatrix() {
int sum = 0;
int a = 0;
for (a = 0; a < i; a++) {
sum = 0;
for (int b = 0; b < j; b++) {
sum = sum + mat[chance][b] * mat2[b][a];
}
result[chance][a] = sum;
}
if (chance >= i)
return;
chance++;
}
}//End multiply class
//Thread Class
class MatrixMultiplier implements Runnable {
private final Multiply mul;
public MatrixMultiplier(Multiply mul) {
this.mul = mul;
}
#Override
public void run() {
mul.multiplyMatrix();
}
}
I just tried on Eclipse and it works, but now I want to create another version of that program in which, I use one thread for each cell that I'll have on the result matrix. For example I've got two 3x3 matrices. So the result matrix will be 3x3. Then, I want to use 9 threads to calculate each one of the 9 cells of the result matrix.
Can anyone help me?
You can create n Threads as follows (Note: numberOfThreads is the number of threads that you want to create. This will be the number of cells):
List<Thread> threads = new ArrayList<>(numberOfThreads);
for (int x = 0; x < numberOfThreads; x++) {
Thread t = new Thread(new MatrixMultiplier(multiply));
t.start();
threads.add(t);
}
for (Thread t : threads) {
t.join();
}
Please use the new Executor framework to create Threads, instead of manually doing the plumbing.
ExecutorService executor = Executors.newFixedThreadPool(numberOfThreadsInPool);
for (int i = 0; i < numberOfThreads; i++) {
Runnable worker = new Thread(new MatrixMultiplier(multiply));;
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
With this code i think that i resolve my problem. I don't use synchronized in the methods but i think that is not necessary in that case.
import java.util.Scanner;
class MatrixProduct extends Thread {
private int[][] A;
private int[][] B;
private int[][] C;
private int rig, col;
private int dim;
public MatrixProduct(int[][] A, int[][] B, int[][] C, int rig, int col, int dim_com) {
this.A = A;
this.B = B;
this.C = C;
this.rig = rig;
this.col = col;
this.dim = dim_com;
}
public void run() {
for (int i = 0; i < dim; i++) {
C[rig][col] += A[rig][i] * B[i][col];
}
System.out.println("Thread " + rig + "," + col + " complete.");
}
}
public class MatrixMultiplication {
public static void main(String[] args) {
Scanner In = new Scanner(System.in);
System.out.print("Row of Matrix A: ");
int rA = In.nextInt();
System.out.print("Column of Matrix A: ");
int cA = In.nextInt();
System.out.print("Row of Matrix B: ");
int rB = In.nextInt();
System.out.print("Column of Matrix B: ");
int cB = In.nextInt();
System.out.println();
if (cA != rB) {
System.out.println("We can't do the matrix product!");
System.exit(-1);
}
System.out.println("The matrix result from product will be " + rA + " x " + cB);
System.out.println();
int[][] A = new int[rA][cA];
int[][] B = new int[rB][cB];
int[][] C = new int[rA][cB];
MatrixProduct[][] thrd = new MatrixProduct[rA][cB];
System.out.println("Insert A:");
System.out.println();
for (int i = 0; i < rA; i++) {
for (int j = 0; j < cA; j++) {
System.out.print(i + "," + j + " = ");
A[i][j] = In.nextInt();
}
}
System.out.println();
System.out.println("Insert B:");
System.out.println();
for (int i = 0; i < rB; i++) {
for (int j = 0; j < cB; j++) {
System.out.print(i + "," + j + " = ");
B[i][j] = In.nextInt();
}
}
System.out.println();
for (int i = 0; i < rA; i++) {
for (int j = 0; j < cB; j++) {
thrd[i][j] = new MatrixProduct(A, B, C, i, j, cA);
thrd[i][j].start();
}
}
for (int i = 0; i < rA; i++) {
for (int j = 0; j < cB; j++) {
try {
thrd[i][j].join();
} catch (InterruptedException e) {
}
}
}
System.out.println();
System.out.println("Result");
System.out.println();
for (int i = 0; i < rA; i++) {
for (int j = 0; j < cB; j++) {
System.out.print(C[i][j] + " ");
}
System.out.println();
}
}
}
Consider Matrix.java and Main.java as follows.
public class Matrix extends Thread {
private static int[][] a;
private static int[][] b;
private static int[][] c;
/* You might need other variables as well */
private int i;
private int j;
private int z1;
private int s;
private int k;
public Matrix(int[][] A, final int[][] B, final int[][] C, int i, int j, int z1) { // need to change this, might
// need some information
a = A;
b = B;
c = C;
this.i = i;
this.j = j;
this.z1 = z1; // a[0].length
}
public void run() {
synchronized (c) {
// 3. How to allocate work for each thread (recall it is the run function which
// all the threads execute)
// Here this code implements the allocated work for perticular thread
// Each element of the resulting matrix will generate by a perticular thread
for (s = 0, k = 0; k < z1; k++)
s += a[i][k] * b[k][j];
c[i][j] = s;
}
}
public static int[][] returnC() {
return c;
}
public static int[][] multiply(final int[][] a, final int[][] b) {
/*
* check if multipication can be done, if not return null allocate required
* memory return a * b
*/
final int x = a.length;
final int y = b[0].length;
final int z1 = a[0].length;
final int z2 = b.length;
if (z1 != z2) {
System.out.println("Cannnot multiply");
return null;
}
final int[][] c = new int[x][y];
int i, j;
// 1. How to use threads to parallelize the operation?
// Every element in the resulting matrix will be determined by a different
// thread
// 2. How may threads to use?
// x * y threads are used to generate the result.
for (i = 0; i < x; i++)
for (j = 0; j < y; j++) {
try {
Matrix temp_thread = new Matrix(a, b, c, i, j, z1);
temp_thread.start();
// 4. How to synchronize?
// synchronized() is used with join() to guarantee that the perticular thread
// will be accessed first
temp_thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return Matrix.returnC();
}
}
You can use Main.java to give 2 matrices that need to be multiplied.
class Main {
public static int[][] a = {
{1, 1, 1},
{1, 1, 1},
{1, 1, 1}};
public static int[][] b = {
{1},
{1},
{1}};
public static void print_matrix(int[][] a) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++)
System.out.print(a[i][j] + " ");
System.out.println();
}
}
public static void main(String[] args) {
int[][] x = Matrix.multiply(a, b);
print_matrix(x); // see if the multipication is correct
}
}
In simple terms, what you all need to do is,
1) Create n (no of cells in resultant matrix) threads. Assign their roles. (Ex: Consider M X N, where M and N are matrices. 'thread1' is responsible for the multiplication of M's row_1 elements with N's column_1 elements and storing the result. This is the value for the resultant matrix's cell_1.)
2) Start each thread's process. (by start() method)
3) Wait until all the threads finish their processes and store the resultant value of each cell. Because those processes should be finished before displaying the resultant matrix. (You can do this by join() methods, and other possibilities too)
4) Now, you can display the resultant matrix.
Note:
1) Since, in this example, the shared resources (M and N) are only used to read only purpose, you don't need to use 'synchronized' methods to access them.
2) You can see, in this program, there are a group of threads running and all of them needs to achieve a specific status by their own, before continuing the next step of the whole program. This multi-threaded programming model is known as a Barrier.
Tried below code in eclipse as per thread for each cell. It works fine, you can check it.
class ResMatrix {
static int[][] arrres = new int[2][2];
}
class Matrix {
int[][] arr = new int[2][2];
void setV(int v) {
//int tmp = v;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
arr[i][j] = v;
v = v + 1;
}
}
}
int[][] getV() {
return arr;
}
}
class Mul extends Thread {
public int row;
public int col;
Matrix m;
Matrix m1;
Mul(int row, int col, Matrix m, Matrix m1) {
this.row = row;
this.col = col;
this.m = m;
this.m1 = m1;
}
public void run() {
//System.out.println("Started Thread: " + Thread.currentThread().getName());
int tmp = 0;
for (int i = 0; i < 2; i++) {
tmp = tmp + this.m.getV()[row][i] * this.m1.getV()[i][col];
}
ResMatrix.arrres[row][col] = tmp;
System.out.println("Started Thread END: " + Thread.currentThread().getName());
}
}
public class Test {
//static int[][] arrres =new int[2][2];
public static void main(String[] args) throws InterruptedException {
Matrix mm = new Matrix();
mm.setV(1);
Matrix mm1 = new Matrix();
mm1.setV(2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
Mul mul = new Mul(i, j, mm, mm1);
mul.start();
// mul.join();
}
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
System.out.println("VALUE: " + ResMatrix.arrres[i][j]);
}
}
}
}
In my solution I assigned to each worker a number of rows numRowForThread equals to: (number of rows of matA) / (number of threads).
public class MatMulConcur {
private final static int NUM_OF_THREAD = 1;
private static Mat matC;
public static Mat matmul(Mat matA, Mat matB) {
matC = new Mat(matA.getNRows(), matB.getNColumns());
return mul(matA, matB);
}
private static Mat mul(Mat matA, Mat matB) {
int numRowForThread;
int numRowA = matA.getNRows();
int startRow = 0;
Worker[] myWorker = new Worker[NUM_OF_THREAD];
for (int j = 0; j < NUM_OF_THREAD; j++) {
if (j < NUM_OF_THREAD - 1) {
numRowForThread = (numRowA / NUM_OF_THREAD);
} else {
numRowForThread = (numRowA / NUM_OF_THREAD) + (numRowA % NUM_OF_THREAD);
}
myWorker[j] = new Worker(startRow, startRow + numRowForThread, matA, matB);
myWorker[j].start();
startRow += numRowForThread;
}
for (Worker worker : myWorker) {
try {
worker.join();
} catch (InterruptedException e) {
}
}
return matC;
}
private static class Worker extends Thread {
private int startRow, stopRow;
private Mat matA, matB;
public Worker(int startRow, int stopRow, Mat matA, Mat matB) {
super();
this.startRow = startRow;
this.stopRow = stopRow;
this.matA = matA;
this.matB = matB;
}
#Override
public void run() {
for (int i = startRow; i < stopRow; i++) {
for (int j = 0; j < matB.getNColumns(); j++) {
double sum = 0;
for (int k = 0; k < matA.getNColumns(); k++) {
sum += matA.get(i, k) * matB.get(k, j);
}
matC.set(i, j, sum);
}
}
}
}
}
where for the class Mat, I used this implementation:
public class Mat {
private double[][] mat;
public Mat(int n, int m) {
mat = new double[n][m];
}
public void set(int i, int j, double v) {
mat[i][j] = v;
}
public double get(int i, int j) {
return mat[i][j];
}
public int getNRows() {
return mat.length;
}
public int getNColumns() {
return mat[0].length;
}
}
For some reason, my method "bishops" runs much faster when called from the main method than from the static initialization block. Is this normal, or a bug?
public class Magic
{
public static void main(String[] args)
{
bishops();
}
public static void bishops()
{
//PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("bishops.txt")));
BISHOP_SHIFTS = new int[64];
BISHOP_COMBOS = new long[64][];
for (int square = 0; square < 64; square++) {System.out.println("bbb " + square);
int NUMBER = bitCount(BISHOP_ATTACKS[square]);
BISHOP_SHIFTS[square] = 64 - NUMBER;
long x = BISHOP_ATTACKS[square];
long[] MAPS = new long[NUMBER];
for (int n = 0; n < NUMBER; n++) {
int i = bitScan(x);
MAPS[n] = (1L << i);
x -= MAPS[n];
}
int C = 1 << NUMBER;
BISHOP_COMBOS[square] = new long[C];
for (int i = 0; i < C; i++) {
BISHOP_COMBOS[square][i] = 0;
int j = i;
for (int n = 0; n < NUMBER; n++) {
if ((j & 1) == 1)
BISHOP_COMBOS[square][i] |= MAPS[n];
j >>>= 1;
}
//out.println("SQUARE " + square);
//out.println(toBitboardString(BISHOP_COMBOS[square][i]));
//out.println();
}
}
//out.close();
bishopMagics();
}
public static void bishopMagics()
{
BISHOP_MAGICS = new long[64];
Random r = new Random();
for (int square = 0; square < 64; square++) {System.out.println("asdffff " + square);
int i;
int LENGTH = BISHOP_COMBOS[square].length;
long magic;
do {
magic = r.nextLong() & r.nextLong() & r.nextLong();
//final int COUNT = bitCount(BISHOP_MASKS[square]);
boolean[] used = new boolean[LENGTH];
for (int j = 0; j < used.length; j++)
used[j] = false;
for (i = 0; i < LENGTH; i++) {
int index = (int) ((BISHOP_COMBOS[square][i] * magic) >>> BISHOP_SHIFTS[square]);
if (used[index])
break;
else
used[index] = true;
}
} while (i < LENGTH);
BISHOP_MAGICS[square] = magic;
System.out.println(magic);
}
//bishopTable();
}
/*
* Lots of stuff omitted
*/
static
{
//bishops();
}
}
It will run much faster the second time than the first as the JVM warms up (loads class es and compiles code). The static block is always called first.
Try running it twice from the main() or the static block and see how long it takes each time
BTW: I would take out any logging to the console as this can slow down the code dramatically.
I want to make a simple math operations on a vector(array) using two cores of my CPU. The program doesn't work correctly. Please explain me how to solve my problem.
public class MyRunnable implements Runnable {
private int startIndex;
private int endIndex;
private float[] tab;
public MyRunnable(int startIndex, int endIndex, float[] tab)
{
this.startIndex = startIndex;
this.endIndex = endIndex;
this.tab = tab;
}
#Override
public void run()
{
System.out.println(Thread.currentThread());
for(int i = startIndex; i < endIndex; i++)
{
tab[i] = i * 2;
}
System.out.println("Finished");
}
}
public class Test {
public static void main(String[] args) {
int size = 10;
int n_threads = 2;
float tab[] = new float[size];
for(int i = 0; i < size; i++)
{
tab[i] = i;
}
System.out.println(Thread.currentThread());
for(int i = 0; i < size; i++)
{
System.out.println(tab[i]);
}
Runnable r1 = new MyRunnable(0, size / n_threads, tab );
Runnable r2 = new MyRunnable(size / n_threads, size, tab );
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
for(int i = 0; i < size; i++)
{
System.out.println(tab[i]);
}
}
It seems like you don't wait for the threads to finish. Use the join method and add
t1.join();
t2.join();
just before the output loop.
As pointed out by others, you are not waiting for your threads to finish execution. You should follow the advice of #Howard and #JK and that will fix your basic issue. If you decide to do more with threads and parallel processing though I would highly advice looking into the java.util.concurrent packages - they have many useful classes that will make your life much easier.
I took the liberty of recoding your example using Callable and ExecutorService. Please see the sample code below:
public static void main(String[] args) {
int size = 10;
int n_threads = 2;
float tab[] = new float[size];
for (int i = 0; i < size; i++) {
tab[i] = i;
}
System.out.println(Thread.currentThread());
for (int i = 0; i < size; i++) {
System.out.println(tab[i]);
}
// Determine batch size, based off of number of available
// threads.
int batchSize = (int) Math.ceil((double) size / n_threads);
System.out.println("Size: " + size + " Num threads: " + n_threads
+ " Batch Size: " + batchSize);
// Create list of tasks to run
List<Callable<Object>> tasks = new ArrayList<Callable<Object>>(
n_threads);
for (int i = 0; i < n_threads; i++) {
tasks.add(Executors.callable(new MyRunnable(i * batchSize,
((i + 1) * batchSize) - 1, tab)));
}
// Create an executor service to handle processing tasks
ExecutorService execService = Executors.newFixedThreadPool(n_threads);
try {
execService.invokeAll(tasks);
} catch (InterruptedException ie) {
ie.printStackTrace();
} finally {
execService.shutdown();
}
for (int i = 0; i < size; i++) {
System.out.println(tab[i]);
}
}
And made one slight change in your MyRunnable class, which was skipping processing on the last index:
#Override
public void run() {
System.out.println(Thread.currentThread());
for (int i = startIndex; i <= endIndex; i++) {
tab[i] = i * 2;
}
System.out.println("Finished");
}
Works great, you can test for yourself. Theres many more classes in java.util.concurrent that can do similar functionality, feel free to explore.
Good luck!
You can wait for the threads to finish execution by inserting calls to Thread.join():
t1.join();
t2.join();
after your x.start() function call to pause until the threads have completed. Otherwise you cannnot know if they are finished executing or not.
You should also consider synchronizing your tab[] accesses within the separate threads with a mutex/semaphore or similar mechanism, and not necessarily perform calculations directly on the passed in array reference, since this can limit the amount of concurrency (if present).