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(); }
}
}
Related
I'm trying to multiply three matrices using threads. I use a number of threads for a matrix multiplication and I should use another number of threads for multiply the result of the two matrices with the last matrices, and I would like to start the threads for the second multiplication as soon as they start having data from the first multiplication result. I'm a little stuck.
What I've tried:
public class Threads implements Runnable{
private String action;
private int range;
public Threads(String action, int range) {
this.action = action;
this.range = range +1;
}
public synchronized void run() {
int k;
int counter = 0;
int m_size = Program.m1.length;
int k_size =Program.m1[0].length;
int n_size = Program.m2[0].length;
int h_size = Program.m3[0].length;
for (int i=0; i<m_size; i++)
for (int j=0; j<n_size; j++) {
counter++;
if (counter % range == 0) {
int val1 = 0;
for (k = 0; k < k_size; k++) {
Program.result[i][j] += Program.m1[i][k] * Program.m2[k][j];
// int val1 =0;
for (int h=0; h<h_size; h++){
val1 += Program.result[i][h] * Program.m3[h][j];
}
}
Program.result_matrix[i][j] = val1; //here run error
}
}
}
public class Program {
private final static Random rand = new Random();
public static int[][] m1 = new int[][]{};
public static int[][] m2 = new int[][]{};
public static int[][] m3 = new int[][]{};
public static int[][] result = new int[][]{};
public static int[][] result_matrix = new int[][]{};
public static void generate(String action, int number_of_threads) throws InterruptedException {
List<Thread> all_threads = new ArrayList<>();
for (int th = 0; th < number_of_threads; th++) {
Thread t = new Thread(new Threads(action, th));
all_threads.add(t);
t.start();
}
for (Thread t : all_threads) {
t.join();
}
}
public static void main(String[] args) throws Exception {
{ //here i m reading the matrices
generate(action, number_of_threads);
print_result_matrix();
public static void print_result_matrix() {
for (int i = 0; i < result_matrix.length; i++) {
for (int j = 0; j < result_matrix[0].length; j++)
System.out.print(result_matrix[i][j] + " ");
System.out.println();
}
}
When I run this program I got an error after setting the matrices rows and columns and gives me error at line //look at code.
Anyway some ideas?I know that my code doesn't have a logic in run() method at the end but I really don't know how to achieve this.
Any ideas?
Stacktrace:
Exception in thread "Thread-0" Exception in thread "Thread-1 java.lang.ArrayIndexOutOfBoundsException: 0
at Threads.run(Threads.java:43)
at java.lang.Thread.run(Thread.java:745) java.lang.ArrayIndexOutOfBoundsException: 0
at Threads.run(Threads.java:43)
at java.lang.Thread.run(Thread.java:745)
You need to initialize result matrices' sizes:
public static int[][] result = new int[m1.length][m2[0].length];
public static int[][] result_matrix = new int[result.length][m3[0].length];
Of course, this should be done after m1, m2 and m3 are filled with data.
Can someone help me with this, please? I'm trying to do a matrix multiplication, using threads. This is what I have so far:
//updated
public class Multiplication {
public static final int NUM_OF_THREADS = 8;
public static final int MATRIX_SIZE = 1000;
public static void main(String args[]) throws InterruptedException {
long startTime = System.currentTimeMillis();
int MatrixA[][] = matrixGenerator();
int MatrixB[][] = matrixGenerator();
int m1rows = MatrixA.length;
int m1cols = MatrixA[0].length;
int m2cols = MatrixB[0].length;
int MatrixC[][] = new int[m1rows][m2cols];
ExecutorService pool = Executors.newFixedThreadPool(NUM_OF_THREADS);
for (int row1 = 0; row1 < m1rows; row1++) {
for (int col1 = 0; col1 < m1cols; col1++) {
pool.submit(new MultiplicationThreading(row1, col1, MatrixA, MatrixB, MatrixC));
}
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.DAYS);
long endTime = System.currentTimeMillis();
System.out.println("Calculated in "
+ (endTime - startTime) + " milliseconds");
}
public static int[][] matrixGenerator() {
int matrix[][] = new int[MATRIX_SIZE][MATRIX_SIZE];
Random r = new Random();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = r.nextInt(10000);
}
}
return matrix;
}
}
//I have updated the code
I get better timings now. When using 2 threads I get 1.5k milliseconds and when I use 8 threads 1.3k milliseconds
You initialize the thrd array with NUM_THREADS == 9 elements. If m1rows*m1cols exceeds that value, you will get this problem, since you attempt to create more than 9 threads and assign them to elements of the array. (You are attempting to create 50 threads).
Two solutions:
Initialize thrd = new Thread[m1rows*m1cols]
Use a List<Thread>.
Note that you won't execute the threads in parallel, because you are calling Thread.join() immediately after calling Thread.start(). This just blocks the current thread until thrd[threadcount] finishes.
Move the Thread.join() calls into a separate loop, so the threads are all started before you call join on any of them.
for (row = 0; row < m1rows; row++) {
for (col = 0; col < m1cols; col++) {
// creating thread for multiplications
thrd[threadcount] = new Thread(new MultiplicationThreading(row, col, MatrixA, MatrixB, MatrixC));
thrd[threadcount].start(); //thread start
threadcount++;
}
}
for (Thread thread : thrd) {
thread.join();
}
I would like to simulate a situation which is mentioned in books about concurrency - that without a proper synchronization one thread can see a stale value of a variable that has been already modified by a different thread. This could happen because for example a CPU cache.
To do this I have written the following program. The idea is that there are 4 threads that initialize a different part of a shared array. The 5th thread (main, parent thread) waits until all 4 previous threads are done, iterates over the shared array and adds its values (always 1 or if I'm lucky null, which would mean a stale value)
package p1;
class ArrFill implements Runnable {
int l, r;
Integer[] arr;
ArrFill(int l, int r, Integer[] arr) {
this.l = l;
this.r = r;
this.arr = arr;
}
#Override
public void run() {
for(int i = l; i < r; i++)
arr[i] = new Integer(1);
}
}
public class Main {
final static int MAX = 10000000;
final static int tnum = 4;
public static void main(String[] args) throws InterruptedException {
int cores = Runtime.getRuntime().availableProcessors();
System.out.println(cores);
Integer[] arr = new Integer[MAX];
Thread[] t = new Thread[tnum];
if(MAX % tnum != 0)
throw new IllegalStateException();
int step = MAX / tnum;
int l = 0, r = 0;
for(int i = 0; i < tnum; i++) {
l = r;
r += step;
t[i] = new Thread(new ArrFill(l, r, arr));
t[i].start();
}
for(int i = 0; i < tnum; i++)
t[i].join();
int res = 0;
for(int i = 0; i < MAX; i++)
if(arr[i] != null)
res += arr[i];
System.out.println(res == MAX);
}
}
I have run this program many times although I never seen a stale value (null). I have 2 cores. Do you have any idea how this program could be improved to actually present the cached value phenomena? Or maybe you have a completly different approach?
Thanks!
I am trying to do a modelling for some algorithms in java, what i am facing now is i need to run the main of the algorithm 10 times but the process takes 120 minutes to finish so i am doing each run on a thread. What i want is to create 10 threads without repeating the same code in each thread so how to make 10 different threads with the same code to excute. any ideas.
package biodavidcorne;
import java.util.Random;
/**
*
* #author hyder
*/
public class BIODavidCorne extends Thread {
public void run(int Runs) {
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
BIODavidCorne test = new BIODavidCorne();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
int Runs = 0;
int[][] Mean10Runs = new int[10][10000];
int[][] Min10Runs = new int[10][10000];
int[][] Max10Runs = new int[10][10000];
// for (int Runs = 0; Runs < 10; Runs++) {
BinList test = new BinList();
Random generator = new Random();
for (int i = 0; i < 10; i++) {
test.ReadLine("File.txt", i);
}
//test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
test.InsertGarbageToBin(i);
}
for (int Big = 0; Big < 10000; Big++) {
int Mean = 0;
for (int x = 0; x < 10; x++) {
for (int i = 0; i < 50; i++) {
test.GetPenalties(x, i);
}
}
// System.out.println("*******************************************************************************************" + Big + " .. " + Runs);
// test.PrintListOfGarbage();
int[] penalty = new int[10];
int[] minimum = new int[10];
int[] maximum = new int[10];
int[] mutation = new int[10];
// test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
penalty[i] = test.getAllPanalties(i);
}
for (int i = 0; i < 10; i++) {
minimum[i] = test.getMinimum(i);
maximum[i] = test.getMaximum(i);
mutation[i] = test.calculateMutation(penalty[i], minimum[i], maximum[i]);
//
}
int r = generator.nextInt(10);
int s = generator.nextInt(10);
test.MakeTheFitness(mutation, r, s);
test.resetPenaltyArray();
// test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
Mean = Mean + mutation[i];
}
int min = mutation[0];
int max = 0;
for (int i = 0; i < 10; i++) {
if (min > mutation[i]) {
min = mutation[i];
}
if (max < mutation[i]) {
max = mutation[i];
}
}
Min10Runs[Runs][Big] = min;
Max10Runs[Runs][Big] = max;
Mean10Runs[Runs][Big] = (Mean / 10);
System.out.println("This is the Mean 1"+Big+".."+Runs);
}
System.out.println("This is the Mean + for Runs" + Runs + ".. " + Mean10Runs[Runs][9999] + "This is the Minimum " + Min10Runs[Runs][9999]);
} catch (Exception e) {
System.out.println("Not supported yet." + e);
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
try {
int Runs = 0;
int[][] Mean10Runs = new int[10][10000];
int[][] Min10Runs = new int[10][10000];
int[][] Max10Runs = new int[10][10000];
// for (int Runs = 0; Runs < 10; Runs++) {
BinList test = new BinList();
Random generator = new Random();
for (int i = 0; i < 10; i++) {
test.ReadLine("File.txt", i);
}
//test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
test.InsertGarbageToBin(i);
}
for (int Big = 0; Big < 10000; Big++) {
int Mean = 0;
for (int x = 0; x < 10; x++) {
for (int i = 0; i < 50; i++) {
test.GetPenalties(x, i);
}
}
// System.out.println("*******************************************************************************************" + Big + " .. " + Runs);
// test.PrintListOfGarbage();
int[] penalty = new int[10];
int[] minimum = new int[10];
int[] maximum = new int[10];
int[] mutation = new int[10];
// test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
penalty[i] = test.getAllPanalties(i);
}
for (int i = 0; i < 10; i++) {
minimum[i] = test.getMinimum(i);
maximum[i] = test.getMaximum(i);
mutation[i] = test.calculateMutation(penalty[i], minimum[i], maximum[i]);
//
}
int r = generator.nextInt(10);
int s = generator.nextInt(10);
test.MakeTheFitness(mutation, r, s);
test.resetPenaltyArray();
// test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
Mean = Mean + mutation[i];
}
int min = mutation[0];
int max = 0;
for (int i = 0; i < 10; i++) {
if (min > mutation[i]) {
min = mutation[i];
}
if (max < mutation[i]) {
max = mutation[i];
}
}
Min10Runs[Runs][Big] = min;
Max10Runs[Runs][Big] = max;
Mean10Runs[Runs][Big] = (Mean / 10);
System.out.println("This is the Mean 2"+Big+".."+Runs);
}
} catch (Exception e) {
System.out.println("Not supported yet." + e);
}
}
});
t1.start();
t2.start();
}
}
Just make the Runnable a named class instead of an anonymous inner class, and reuse it:
class MyRunnable implements Runnable {
#Override
public void run() {
int Runs = 0;
int[][] Mean10Runs = new int[10][10000];
// ...
new Thread(new MyRunnable()).start();
You can (and should) put MyRunnable in its own source file.
There is no reason to copy and paste the content of the anonymous inner class ten times. Just assign it to a variable and use it 10 times.
Runnable runnable = new Runnable() {
#Override
public void run() {
// ... the code in the anonymous inner class
}
}
// Start 10 threads with this code
for (int i = 0; i < 10; ++i) {
new Thread(runnable).start();
}
You can use a for loop to create the threads.
Also, if you want to ensure that all of the threads kick off at the same time, you can use a CyclicBarrier, but if not you can just start each thread as you create it.
If you need to hold a reference to the threads, store them in a Thread array
CyclicBarrier barrier = new CyclicBarrrier(10);
// Runnable runnable = ... your code. at the beginning of the Runnable put the first line
barrier.await(); // and catch the exception
Thread[] threads = new Thread[10];
for(int i = 0; i < 10; i++){
threads[i] = new Thread(runnable);
threads[i].start();
}
That's it! Good luck - let me know if you need help implementing the runnable
Unless you have 10 CPU cores do not spawn 10 threads.
You can use commons threadpool and set it the size of the number of cpu cores, so you can run the tasks in parallel and sequentially.
try using a ThreadPoolExecutor
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html
Create a class that extends Thread and implement the run method. You could pass argument through the constructor, keep them as members to use them in the run() method.
Something like this:
public class YourThread extends Thread{
private String mParam1;
private Object mParam2;
public YourThread( String param1, Object param2 ){
mParam1 = param1;
mParam2 = param2;
}
public void run(){
// do your stuff here
// ...
}
}
In the other class:
YourThread t1 = new Thread( "toto", new Object() );
t1.start();
YourThread t2 = new Thread( "titi", new Object() );
t2.start();
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).