What is the difference between Thread.join and Synchronized?

I am confused when to use Thread.join() and when to use synchronization in an application with multiple threads.

According to my words, they block or wait for the execution of some other thread.
This example should print 10 A, 10 B and 10 C in a sequential pattern one after another, for example:

 1 : A 2 : A 3 : A 4 : A 5 : A 6 : A 7 : A 8 : A 9 : A 10 : A 1 : B 2 : B 3 : B 4 : B 5 : B 6 : B 7 : B 8 : B 9 : B 10 : B 1 : C 2 : C 3 : C 4 : C 5 : C 6 : C 7 : C 8 : C 9 : C 10 : C ----ProGraM ENDS---- 

Example starts here

 class SyncTest extends Thread { StringBuffer sb; public SyncTest(StringBuffer sb) { this.sb = sb; } public void run() { synchronized(sb) { for(int i=1;i<=10;i++){ System.out.println(i+" : "+sb.charAt(0)); } sb.setCharAt(0, (char) (sb.charAt(0)+1)); } } public static void main(String [] args) throws InterruptedException { StringBuffer sb = new StringBuffer("A"); Thread t1=new SyncTest(sb); Thread t2=new SyncTest(sb); Thread t3=new SyncTest(sb); t1.start(); t2.start(); t3.start(); Thread.sleep(1000); System.out.println("----ProGraM ENDS----"); } } 

Here, the output is 10 A, followed by 10 B, and then 10 C in sequential order. But I can use Thread.join instead of the synchronized block to get the same output as this:

 public void run() { //removed synchronized statement... for(int i=1;i<=10;i++){ System.out.println(i+" : "+sb.charAt(0)); } sb.setCharAt(0, (char) (sb.charAt(0)+1)); } public static void main(String [] args) throws InterruptedException { StringBuffer sb = new StringBuffer("A"); Thread t1=new SyncTest(sb); Thread t2=new SyncTest(sb); Thread t3=new SyncTest(sb); t1.start(); t1.join(); t2.start(); // wait for t1 to complete t2.join(); t3.start(); // wait for t2 to complete t3.join(); // wait for t3 to complete System.out.println("----ProGraM ENDS----"); } 

Can anyone clear my confusion about using these two methods, that is, when to use Thread.join and when to use synchronization in multithreading in Java.

+11
source share
6 answers

Thread.join() expects a thread to complete completion, while a synchronized block can be used to prevent two threads from simultaneously executing the same piece of code.

It is difficult to advise when to use one over the other as a whole, since they serve different purposes. It’s rare to find an example, for example, your code, where the difference between them is minimal.

As they say, in your first example there is no guarantee that the result will be alphabetical. You cannot be sure which thread will first go to the synchronized block. Therefore, in this particular case, join() is most appropriate.

+14
source

thread.join() stops the execution of the current thread until the merged thread completes .. You commented correctly .. :)

Synchronization prevents multiple threads from executing the synchronized portion of code in a single instance.

+5
source

The synchronized includes a locking mechanism that prevents threads from stepping on one another. The Java documentation describes this as a way of "preventing thread interference and memory consistency errors."

If you use join() , it ensures that as soon as the thread calls the connection, the current thread (the current thread) will not be executed if the thread that you called the join is completed. I think the diagram below may help to visualize this better.

enter image description here

A source

+4
source

Without join() thread runs in parallel and depends on the OS time slice (for starters). With join() thread is executed sequentially. For example: Suppose you have two threads calling the join() method

 MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); t1.join(); // this will be start first. t2.join(); // this will be start only after above. 

Now, without join() you can start with any of t1 and t2 . There is no guarantee.

synchronized statement / keyword is used to control the flow, so only one thread can access this synchronized method / variable at a time. It doesn't matter if you use join() or not.

If you use synchronized with join() , you have the guarantee that t1 can only be accessed first. Without synchronized thread t1 and t2 can access at any time, but these threads start and die. sequentially due to join() .

+2
source

They obviously do not match, but if they are used for the same purpose (access / execution serialization), then synchronized blocks can be considered as a more flexible version than using unions, since the use is agnostic with respect to the specific thread of the instances for which you want to execute serialization.

In addition, in synchronized blocks, the concept of a common data block is more emphasized than combining.

+1
source

A simple example:

You have a static row table in which some threads will put some values. The table is initialized to empty. the table is accessed by a static index. If the thread puts a value, it will increase the static index.

If you are synchronizing threads, make sure that any value specified by the thread cannot be overridden by another thread.

if you are using a join by streams, only the first linked stream will be able to put the values ​​in the table. Since the other will wait, but knowing that the index will be increased, they will not be able to access the table (null pointer exception). Thus, Join made the other thread useless.

This example uses streams of a single instance containing a synchronized method.

0
source

Source: https://habr.com/ru/post/1208110/


All Articles