0

My task is to create x Threads, and in some way to use MethodA and B, and synchronize them, and to catch some Exception in the end. I know this is not a really good description of the task, but this is how I got the task.

So the question is, would this code do, what the task is asking for? Are these Threads synchronized correctly or not?

public class Test2{

    public static synchronized void doActionA(){
        System.out.println("Hi");
    }

    public static synchronized void doActionB(){
        System.out.println("Hello");
    }

    public static void main(String[] args) {
        
        for(int i = 0; i < 10000; ++i){
            try{
                new Thread(() -> {
                    doActionA();
                    doActionB();
                }).start();  
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                System.out.println(":)");
            }
        }
    }
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Haoshoku
  • 27
  • 1
  • 5
  • I'm not really sure what the task is asking for, but I can say that the `synchronized` keyword on both your methods is doing absolutely nothing because `System.out.println()` is a synchronized method itself. – Charlie Armstrong Jul 27 '20 at 19:40
  • Do you want to create 10k threads ? I don't recomment it. Use a threadPool via Executors or smth. Second thing is your exception catching is not useful as they can't catch the exception inside another thread. – cool Jul 27 '20 at 19:40
  • @CharlieArmstrong: Let's assume, whatever inside the Methods were not synchronized, would these Threads be synchronized then? I am going to write a programming exam in 2 days, and they want to see whether we understand the concepts or not, and this task could be in the exam in this kind, or a little different. – Haoshoku Jul 27 '20 at 19:44
  • @cool: I probably only need 100 Threads, but for the purpose of printing in the console i did it 10k. Executors will also be a part of the exam, so i could try it that way also. – Haoshoku Jul 27 '20 at 19:48
  • 2
    What exactly do you mean by "synchronize them"? This will ensure that at most one thread is executing `doActionA` or `B` at a time, but there is no guarantee they won't be interspersed (as in, it might print `Hi Hello Hi Hello` or `Hi Hi Hello Hello` etc). – Andy Turner Jul 27 '20 at 19:49

3 Answers3

1

This is mostly useless, yeah.

You have 10000 threads. Each thread is going to perform the following task pattern:

NB: Take the object "Test2.class" (the instance of java.lang.Class that represents the Test2 class; there is only one such object in the entire VM loaded. We shall call this 'the locker'.

  1. Check the locker object for its 'monitor' thread. If it is unset, set yourself as the monitor thread of the locker and continue. (and do all that atomically). If not, freeze the thread until the 'monitor' is null again, and then compete with the 9999 other threads that want to set it; only one of the 9999 wins, sets itself as the monitor, and continues. The remainining 9998 will freeze and wait another round.

  2. Execute doActionA. All the while, 9999 threads are twiddling thumbs.

  3. Relinquish the locker (unset yourself as the monitor of the locker). 9999 other threads all fly in to set themselves as monitor. Only one of those will 'win'.

  4. Acquire the lock again (set yourself as the monitor of the locker if it is currently unset; otherwise, freeze and wait until it is available.. and do that atomically). Depending on the JVM implementation, this thread may in fact 'win', and take the monitor riiight back, beating the other 9999 threads.

  5. Execute doActionB. During this job, 9999 threads are twiddling thumbs doing absolutely nothing whatsoever. Just waiting around.

  6. Relinquish the monitor and exit. Pfew. 9999 more to go.

As you can tell, this pattern most likely means this code runs as fast as just:

for (int i = 0; i < 10000; i++) {
    doActionA();
    doActionB();
}

except the above most likely runs FAR faster, as your example first allocates 1.25 gigabytes worth of memory just to store stacks (each thread needs a stack, and here's praying your stacks are 'just' 128k large, they are often larger), and wastes a ton of time juggling thread states for pretty much no purpose.

This is not how you thread things.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
1

Are these Threads synchronized correctly or not?

"Synchronized" in what way? "Synchronized" for what purpose?

It's "correct" if the program is guaranteed to do what you want it to do. What do you want this program to do?

What it will do is, it will print print ten thousand complete lines of "Hi", and it will print ten thousand complete lines of "Hello", and it will print them in no particular order. The reason each line will be complete is that the System.out object uses synchronization to ensure that at most one thread at a time can execute println(...). The reason why the lines will be printed in no particular order is, there isn't any other synchronization between the threads in the program.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
0

This is the main part of your task: catch some Exception in the end.

The question is: would this code do what the task is asking for?

No, becasue exception happened inside a thread can not be caught outside of the thread like this, read the following question for more information:

How to catch an Exception from a thread

Tashkhisi
  • 2,070
  • 1
  • 7
  • 20