Concurrency Multithreading

  • (2 Pages)
  • +
  • 1
  • 2

27 Replies - 1614 Views - Last Post: 26 April 2019 - 02:07 PM Rate Topic: -----

#16 overwhelmed_student   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 63
  • Joined: 10-May 18

Re: Concurrency Multithreading

Posted 26 April 2019 - 09:09 AM

View Postxclite, on 26 April 2019 - 08:44 AM, said:

  • Even better would be to submit these Runnables to an ExecutorService
  • Once you get the threads running concurrently, you're going to need a way to wait on them.
  • I really recommend obliterating your use of static. These values are shared across all threads, so when you modify "start" from the main thread, you modify it for all the threads. Instead, give the threads their positions in the constructor (when you call new).
  • I'd also recommend separating your main method from the things it is creating and running, which will help manage state.


I really really want to emphasize: If you want to write Good Code in Java, you should very rarely be using "static".


I got a few questions here. I used static because the main method is static and there is always something wrong with static calling non-static. I will try to use different classes so that my main-class only has the main-method and my runnable class does everything else. Hopefully, this way I don't need to use static at all (only for the main-method). I am just coding and appreciate any help about my coding style. This is not covered in my class.

And you mentioned ExecutorService, like a threadpool? I can do that. I just wanted to understand the whole concept but during my research I learned how to implement a threadpool.

As for waiting, I only know about wait(), notify() and notifyAll(). But I thought I can only use it in synchronized block which (as far as I know) I don't have.
Was This Post Helpful? 0
  • +
  • -

#17 xclite   User is offline

  • I wrote you an code
  • member icon


Reputation: 1380
  • View blog
  • Posts: 4,206
  • Joined: 12-May 09

Re: Concurrency Multithreading

Posted 26 April 2019 - 09:20 AM

View Postoverwhelmed_student, on 26 April 2019 - 12:09 PM, said:

I got a few questions here. I used static because the main method is static and there is always something wrong with static calling non-static.

You nailed it - basically just let the main method drive. Don't manage state in it. Try to separate individual actors, objects, "things" into their own classes, which own their own, private state.

Quote

And you mentioned ExecutorService, like a threadpool? I can do that. I just wanted to understand the whole concept but during my research I learned how to implement a threadpool.

Yup, I'd use https://docs.oracle....ThreadPool(int)

Quote

As for waiting, I only know about wait(), notify() and notifyAll(). But I thought I can only use it in synchronized block which (as far as I know) I don't have.


There are a lot of ways to do this. If you're doing threads, you can call "join" on each thread to wait until it's done.

With the ExecutorService, if you submit your Runnables, you can then call "shutdown" on it followed by awaitTermination, and it will let the submitted things finish up before shutting down.

There are also fancy things like sempahores and CountDownLatches but you don't need that right now.
Was This Post Helpful? 1
  • +
  • -

#18 overwhelmed_student   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 63
  • Joined: 10-May 18

Re: Concurrency Multithreading

Posted 26 April 2019 - 10:21 AM

View Postxclite, on 26 April 2019 - 09:20 AM, said:

With the ExecutorService, if you submit your Runnables, you can then call "shutdown" on it followed by awaitTermination, and it will let the submitted things finish up before shutting down.

There are also fancy things like sempahores and CountDownLatches but you don't need that right now.


This is all self learning so I hope I used it the right way:
public class MyRunnablePlay{
    int [] array;
    int start;
    int end;
    int threadNo;

    MyRunnablePlay(int[] array, int start, int end, int threadNo) {
        this.array = array;
        this.start = start;
        this.end = end;
        this.threadNo = threadNo;
    }

    public void incrementValues(int[] array, int start, int end) {
        if(end <= array.length && start < end) {
            for (int i = start; i < end; i++) {
                array[i] = array[i] + 1;
            }
        }
    }

    public void createThreads() {
        ExecutorService threadPool = Executors.newFixedThreadPool(threadNo);

        for(int i = 1; i <= threadNo; i++) {
            threadPool.submit(() -> incrementValues(array, start, end));
            start = end;
            end = end+(array.length/threadNo);
        }

        threadPool.shutdown();

        try {
            threadPool.awaitTermination(2, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}



Unfortunately, my code doesn't increment the values anymore. And awaitTermination() waits for the threads, does it matter which parameters I put there? Also, the time and when I print the array (I went back to a smaller array to see what happens), it prints all that randomly in between. I tried join() in the main-method and in this class but my program never terminates once I do that. Needless to say I am quite confused.
Was This Post Helpful? 0
  • +
  • -

#19 xclite   User is offline

  • I wrote you an code
  • member icon


Reputation: 1380
  • View blog
  • Posts: 4,206
  • Joined: 12-May 09

Re: Concurrency Multithreading

Posted 26 April 2019 - 10:44 AM

The Runnable should be responsible for exactly one thing. That thing? When run, increment the numbers it cares about. Creating threads, assigning work to the threads, and waiting for them should be done elsewhere. Think about it for a second: when you modify "start" here as you create new workers, what is the "start" variable you're modifying? The same one that is being worked on.
Was This Post Helpful? 1
  • +
  • -

#20 overwhelmed_student   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 63
  • Joined: 10-May 18

Re: Concurrency Multithreading

Posted 26 April 2019 - 11:35 AM

View Postxclite, on 26 April 2019 - 10:44 AM, said:

Creating threads, assigning work to the threads, and waiting for them should be done elsewhere. Think about it for a second: when you modify "start" here as you create new workers, what is the "start" variable you're modifying? The same one that is being worked on.


I think I have done this now. However, I also think I need to use join() in order to wait for every thread to finish before I print (for example) the time. How do I do that? With the threadpool or even the for-loop, my threads do not have a name I can use. I thought, it is like this:
Thread t1 = new Thread();
t1.start();
t1.join();



In this case, my current thread waits for t1 to finish before continuing the execution. Did I get that wrong?
I was thinking of putting wait() but I wouldn't even know which thread needs to wait or which needs to notify everyone. I am so confused. It hasn't been long since I started to learn about threads and my program suddenly doesn't execute line by line anymore. I don't know how to keep the order. Thank you for being so patient with me.
Was This Post Helpful? 0
  • +
  • -

#21 xclite   User is offline

  • I wrote you an code
  • member icon


Reputation: 1380
  • View blog
  • Posts: 4,206
  • Joined: 12-May 09

Re: Concurrency Multithreading

Posted 26 April 2019 - 12:09 PM

Methods like "wait" are related, but ancient ways of handling posix-style wait conditions. I think your path is right - in a naive case, let's say you have 4 threads.

You could do something like:
Thread t1, t2, t3, t4;
t1 = new Thread(new Runnable(someStart, someEnd...));
t1.start();
t2 = ...
t2.start();
t3 = ...
t3.start();
t4 = ...
t4.start();
t1.join();
t2.join();
t3.join();
t4.join();



If you were feeling industrious, you could put them in an array and then join each thread in the array.
Was This Post Helpful? 1
  • +
  • -

#22 overwhelmed_student   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 63
  • Joined: 10-May 18

Re: Concurrency Multithreading

Posted 26 April 2019 - 12:17 PM

View Postxclite, on 26 April 2019 - 12:09 PM, said:

If you were feeling industrious, you could put them in an array and then join each thread in the array.


I was thinking the same! I stopped using the threadpool because I was unsure how to handle that. Instead, I used a for-loop to create my threads and while I created them, I added them to the array:
My array:
    Thread[] threads;

    MyRunnablePlay(int[] array, int start, int end, int threadNo) {
        this.array = array;
        this.start = start;
        this.end = end;
        this.threadNo = threadNo;
        threads = new Thread[threadNo];
    }



Where I use it:
    public Thread[] createThreads() {
        for(int i = 0; i < threadNo; i++) {
            Thread t = new Thread(new MyRunnable(array, start, end, threadNo));
            threads[i] = t;
            t.setName("t" + (i+1));
            t.start();
            values();
        }
        return threads;
    }



And where I call it:
    public static void main(String[] args) {
        int threadNo = 4;
        int[] array = new int[100000000];
        int start = 0;
        int end = array.length/threadNo;

        System.out.println("Running on " + threadNo + " threads.");
        MyRunnablePlay tmp = new MyRunnablePlay(array, start, end, threadNo);

        double time = System.currentTimeMillis();
        Thread [] threads = tmp.createThreads();

        for(int i = 0; i < threads.length; i++) {

            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        double stop = System.currentTimeMillis();
        System.out.println("Time: " + (stop - time) + "ms");
    }


Hopefully, I get the right time and it is still concurrent. Is it?
I just wanted to have to change only the amount of threads once and not in all parts of the code.
Was This Post Helpful? 0
  • +
  • -

#23 xclite   User is offline

  • I wrote you an code
  • member icon


Reputation: 1380
  • View blog
  • Posts: 4,206
  • Joined: 12-May 09

Re: Concurrency Multithreading

Posted 26 April 2019 - 12:43 PM

Might be worth trying to find that out yourself! How might you prove to yourself that your threads are working at the same time?
Was This Post Helpful? 1
  • +
  • -

#24 overwhelmed_student   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 63
  • Joined: 10-May 18

Re: Concurrency Multithreading

Posted 26 April 2019 - 12:55 PM

View Postxclite, on 26 April 2019 - 12:43 PM, said:

Might be worth trying to find that out yourself! How might you prove to yourself that your threads are working at the same time?


I only tried it in two different ways. First way: I added a simple println() with "Thread x running" and "Thread x done" in the run method. I thought if the second thread starts running before the first thread is done, it should be working. The second way didn't quite work out because I thought if I start with 1 thread and go up to 2, 4 and 8 I would see a difference in the time-print but I get results that show me nothing really.
Was This Post Helpful? 0
  • +
  • -

#25 xclite   User is offline

  • I wrote you an code
  • member icon


Reputation: 1380
  • View blog
  • Posts: 4,206
  • Joined: 12-May 09

Re: Concurrency Multithreading

Posted 26 April 2019 - 01:26 PM

What if, for testing purposes, you printed inside of each thread's loop? Something like "thread 1 incrementing index 4"?

If things were running at the same time, how would that look?
Was This Post Helpful? 1
  • +
  • -

#26 overwhelmed_student   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 63
  • Joined: 10-May 18

Re: Concurrency Multithreading

Posted 26 April 2019 - 01:41 PM

View Postxclite, on 26 April 2019 - 01:26 PM, said:

If things were running at the same time, how would that look?


I did what you suggested and my output is not in order. It's like: t1, t1, t1, t1, t2, t2, t2, t2, t1, t1, t2, t2 etc.
This is what I would have expected if threads were running at the same time. While it is mostly still big parts for t1 and then t2 (or vice versa), it doesn't change too frequently, I am not sure if it should be 100% alternating between those two threads. But many times it is totally in order, I don't know what to think of that.

This post has been edited by overwhelmed_student: 26 April 2019 - 01:42 PM

Was This Post Helpful? 0
  • +
  • -

#27 xclite   User is offline

  • I wrote you an code
  • member icon


Reputation: 1380
  • View blog
  • Posts: 4,206
  • Joined: 12-May 09

Re: Concurrency Multithreading

Posted 26 April 2019 - 02:02 PM

You could be seeing the OS give preference to the current thread rather than swapping constantly if you have a small number of cores. If they interleave on runs, you can be sure it's running concurrently.
Was This Post Helpful? 1
  • +
  • -

#28 overwhelmed_student   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 63
  • Joined: 10-May 18

Re: Concurrency Multithreading

Posted 26 April 2019 - 02:07 PM

Thank you so much for your help! :)
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2