Good afternoon, I recently read Bruce Ekkel, and came across such a problem: the synchronized (Object) block blocks the object's class, it’s not the object itself. I came to this conclusion after executing this code:

public class Main { public static void main(String[] args) { Sync s = new Sync(); new Thread(new Runnable() { @Override public void run() { s.go(); } }, "First").start(); new Thread(new Runnable() { @Override public void run() { s.go(); } }, "Second").start(); } } class Sync { private Writer w1, w2; public Sync() { w1 = new Writer(); w2 = new Writer(); } public void go() { synchronized (w2) { w1.log(Thread.currentThread().getName() + "...1"); //!Этот блок кода должен выполнятся паралельно во всех потоках, но выполняется последовательно. w2.log(Thread.currentThread().getName() + "...2"); //Этот должен выполнятся последовательно, и он так и делает. } } } class Writer { public void log(Object obj) { for (int i = 0; i < 5; i++) { lgn(obj); try { TimeUnit.MILLISECONDS.sleep(750); } catch (InterruptedException e) { e.printStackTrace(); } } } } 

Why, when locking w2, does it block w1? These are different objects?

The book and all sources speak about locking in a synchronized object! If I did something wrong or did not understand something, then could you answer me why and how?

Conclusion

 First...1 First...1 First...1 First...1 First...1 First...2 First...2 First...2 First...2 First...2 Second...1 Second...1 Second...1 Second...1 Second...1 Second...2 Second...2 Second...2 Second...2 Second...2 

Expected output

 First...1 Second...1 First...1 Second...1 First...1 Second...1 First...1 Second...1 First...1 Second...1 First...2 First...2 First...2 First...2 First...2 Second...2 Second...2 Second...2 Second...2 Second...2 
  • Synchronization occurs on the object specified in synchronized, and you always have it w2, therefore w1 always smokes bamboo and you think that synchronization takes place according to the class - Dmitry
  • Is it possible in more detail, I just did not understand how an independent object w2 with its synchronization can affect the synchronization w1? - NikitaGordia
  • Let us on the other hand ... Try to replace the method so public synchronized void go () {w1.log (Thread.currentThread (). GetName () + "... 1"); System.out.println (" "); //! This code block should be executed in parallel in all threads, but executed sequentially. w2.log (Thread.currentThread (). getName () + "... 2"); System.out.println ("* "); // This should execute consistently, and it does. } - Dmitriy
  • See how it is done, it may clarify the situation ... - Dmitry

1 answer 1

Your comments in the code:

 synchronized (w2) { w1.log(Thread.currentThread().getName() + "...1"); //!Этот блок кода должен выполнятся паралельно во всех потоках, но выполняется последовательно. w2.log(Thread.currentThread().getName() + "...2"); //Этот должен выполнятся последовательно, и он так и делает. } 

are wrong.

The synchronized section does not synchronize an object , but a piece of code . This means that the entire section will be executed “in one piece”, without interrupting the other section with the same synchronization object (this is just your case).

Thus, first the code in the stream "First" comes to the synchronization section and executes it completely , and only then the stream "Second" . (Well, or in reverse order, how lucky.)

  • OK, let's say I understood, but if only one thread is pierced through this block of code, then why do we need to throw something else into the parameters? (brackets) - NikitaGordia
  • @NikitaGordia: Well, sections that are synchronized across different objects are independent. Otherwise, if you have one piece of code synchronized, then all other synchronized pieces in the entire program will wait for it , even if you don’t need it. - VladD