use join in threads loop - java

I'm learning to use threads in java, since I want to speed up a task to reduce time. I try to see how long it takes to finish the threads but since I don't know how to use join in this case:
public class MyThread1 extends Thread {
int inicio;
int fin;
public MyThread1(int _inicio, int _fin) {
this.inicio = _inicio;
this.fin = _fin;
}
#Override
public void run() {
String pass;
for(int i = inicio; i < fin; i++){
pass = Integer.toString(i);
System.out.println(pass);
}
}
}
public static void main(String arg[]) throws UnknownHostException {
long previousTime;
previousTime = System.currentTimeMillis();
int threads = 10; // Number of threads
for (int i = 0; i < threads; i++) {
MyThread1 object = new MyThread1(0,10);
object.start();
}
long currentTime = System.currentTimeMillis();
double elapsedTime = (currentTime - previousTime) / 1000.0;
System.out.println("Time in seconds : " + String.valueOf(elapsedTime));
}

Add MyThread1 object to an array that is declared before the loop. After the loop, have another loop which will join on all objects.
for (int i = 0; i < threads; i++) {
MyThread1 object = new MyThread1(0,10);
arr[i] = object;
object.start();
}
for (int i = 0; i < threads; i++) {
arr[i].join();
}

Related

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();
}

Why is value set correctly even though we use different locks in different threads

Why is value set correctly even though we use different locks in different threads?
public class MyThread implements Runnable {
static String a = "LOCK";
static String b = "LOCK";
int id;
static int value = 0;
MyThread(int id) {
this.id = id;
}
#Override
public void run() {
if (id == 0) {
synchronized (a) {
for (int i = 0; i < Main.N; i++)
value = value + 3;
}
} else {
synchronized (b) {
for (int i = 0; i < Main.N; i++)
value = value + 3;
}
}
}
}
public class Main {
static final int N = 100000;
static int ITER = 100;
public static void main(String[] args) {
Thread threads[] = new Thread[2];
boolean sw = true;
for (int j = 0; j < ITER; j++) {
MyThread.value = 0;
for (int i = 0; i < 2; i++)
threads[i] = new Thread(new MyThread(i));
for (int i = 0; i < 2; i++)
threads[i].start();
for (int i = 0; i < 2; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (MyThread.value != 2 * 3 * N) {
System.out.println("i was different than " + 2 * 3 * N + ", it is " + MyThread.value);
sw = false;
}
}
if (sw)
System.out.println("Something is strange");
}
}
Java string literals are interned to save memory.
Your two "LOCK" strings (and therefore the two objects you lock on) are actually the same object.
This is (one of the reasons) why you should never lock on primitives.
Never use String as locks as there may well be the same instance of an other String because of the string pool.
In your case, your two "LOCK" strings are actually the same object.

How to achieve synchronization of three threads using reentrant lock?

Below specified code snippet prints numbers in sequence with synchronizing three threads using wait() and notify() methods. But the requirement is to achieve the same using reentrant locking mechanism.
class JoinTask {
private int currentRank = 1;
public void doJob(int rank, int printNo) {
synchronized (this) {
while (rank != currentRank) {
try {
System.out.println("going to wait by thread:" + printNo);
wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("Job:" + printNo + " : " + currentRank);
currentRank++;
notifyAll();
}
}
}
public class ThreeThreadsPlay {
public static void main(String[] args) {
final JoinTask task = new JoinTask();
Thread A = new Thread() {
public void run() {
int k = 1;
for (int i = 1; i < 30; i++) {
task.doJob(k, 1);
k = k + 3;
}}};
Thread B = new Thread() {
public void run() {
int k = 2;
for (int i = 1; i < 30; i++) {
task.doJob(k, 2);
k = k + 3;
}}};
Thread C = new Thread() {
public void run() {
int k = 3;
for (int i = 1; i < 30; i++) {
task.doJob(k, 3);
k = k + 3;
}}};
C.start();
B.start();
A.start();
}}
How can I achieve the same using reentrant locking?
Any other example using reentrant locking to provide such mechanism will also help. Furthermore, any information provided in this context will be highly appreciated.
Here's a proper implementation with ReentrantLock/Conditional. Note carefully the differences between this and what you attempted. The lock acquisition and release should really be handled in a try-finally block to avoid a lock being kept indefinitely, but you can find examples of that in other questions.
class JoinTask {
private int currentRank = 1;
final ReentrantLock l = new ReentrantLock();
final Condition c = l.newCondition();
public void doJob(int rank, int threadNumber) {
l.lock();
while(rank != currentRank) {
c.await();
}
System.out.println("Job:" + threadNumber + " : " + currentRank);
currentRank++;
c.signalAll();
l.unlock();
}
}

Division of a task to threads - multi threading

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.

How do i wait for all threads in java code here?

I would like to compare thread performance on solaris/linux/windows 64 bit JVM's, with the below code.
I personally, prefer this style of coding for threading, because you have a method performing some computation and you would like to run that computation on separate thread. It does not look intuitive for me launch an object using Thread class. So, Please suggest me for alternate code style, on same lines(if required).
public class Dummy2 {
private static int NUM_OF_THREADS=100000;
public void loopSomeTime() {
Thread t = new Thread(new Runnable(){
public void run(){
int count = 0;
for(int i = 0; i < 1000000; ++i){
count++;
}
System.out.println(count);
}
});
t.start();
}
public static void main(String[] args){
long beginTime = System.nanoTime();
for(int i =0; i < NUM_OF_THREADS ; i++){
Dummy2 d = new Dummy2();
d.loopSomeTime();
}
//I need to wait here
long endTime = System.nanoTime() - beginTime;
System.out.println(endTime/(1000*1000) + "milliseconds");
}
}
How do i wait for all threads to complete before the computation of endTime in MainThread?
Note: I am java beginner and learning Java threads
The key here is you need some way to wait for all of the threads to complete. However, threads are low-level constructs that are a pain to manage correctly.
Using higher-level constructs, you can push some of the tricky dirty work into the Java framework and focus on what you are trying to do: waiting for the threads to complete.
Here is some Java that illustrates the overall design I recommend. It is not complete, but should be a good start.
public static void main(String[] args) {
final int threads = 1000;
ExecutorService exec = Executors.newFixedThreadPool(threads);
List<Future<?>> futures = new LinkedList<>();
final long start = System.currentTimeMillis();
for (int i = 0; i < threads; ++i) {
futures.add(exec.submit(makeTask()));
}
while (!futures.isEmpty()) {
Iterator<Future<?>> it = futures.iterator();
while (it.hasNext()) {
if (it.next().isDone()) {
it.remove();
}
}
}
final long duration = System.currentTimeMillis() - start;
// TODO: report the difference.
}
private static Runnable makeTask() {
// TODO: return a Runnable that does stuff.
return null;
}
You need to keep track of all of the threads and call join on each one.
public class Test {
private static int NUM_OF_THREADS = 100000;
// Keep track of my thread.
private Thread thread;
public void loopSomeTime() {
thread = new Thread(new Runnable() {
public void run() {
int count = 0;
for (int i = 0; i < 1000000; ++i) {
count++;
}
System.out.println(count);
}
});
thread.start();
}
public void waitToFinish() throws InterruptedException {
thread.join();
}
public static void main(String[] args) throws InterruptedException {
List<Test> loopers = new ArrayList<>();
long beginTime = System.nanoTime();
for (int i = 0; i < NUM_OF_THREADS; i++) {
Test d = new Test();
d.loopSomeTime();
// Keep track of all loopers.
loopers.add(d);
}
//I need to wait here
for (Test t : loopers) {
t.waitToFinish();
}
long endTime = System.nanoTime() - beginTime;
System.out.println(endTime / (1000 * 1000) + "milliseconds");
}
}

Categories

Resources