As far as I understand, the ReentrantLock class is an alternative to synchronized. And its tasks are to synchronize threads, if they work with a common object.

If something goes wrong, correct it.

public class TestMultithreading{ static int count = 0; // совмСстный ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² Π½Π° 2 ΠΏΠΎΡ‚ΠΎΠΊΠ° public static void main(String[] args){ Thread t1 = new Thread(new Client()); Thread t2 = new Thread(new Client()); t1.start(); t2.start(); } } public class Client implements Runnable{ Lock lock = new ReentrantLock(); @Override public void run() { while (TestMultithreading.count <= 10) { lock.lock(); System.out.println(Thread.currentThread().getName() + " " + TestMultithreading.count); TestMultithreading.count++; lock.unlock(); } } 

Right:

 Thread-0 0 Thread-0 1 Thread-0 2 Thread-0 3 Thread-0 4 Thread-0 5 Thread-0 6 Thread-0 7 Thread-0 8 Thread-0 9 Thread-0 10 Thread-1 0 

Wrong:

 Thread-0 0 Thread-0 1 Thread-0 2 Thread-1 0 Thread-1 4 Thread-1 5 Thread-0 3 Thread-1 7 Thread-1 8 Thread-1 9 Thread-1 10 Thread-0 8 

The result is correct once every other time. Why is that?

    2 answers 2

    First, in your case, each thread is synchronized by its blocking, which does not exclude simultaneous access of threads to a shared variable. Those. the lock should be common to the common variable.

    Secondly, the two examples of output you give are not what you expect, because the thread gets a lock on each iteration of the loop, not on the whole loop. Those. even if you rewrite the code using a general blocking, you will still get different results.

    • How can I implement point 1? - romashechka
    • one
      @romashechka So I said everything, you need one common instance of ReentrantLock , and not two. - a_gura
    • on account of point 2, with general ReentrantLock, everything works fine and stable - romashechka
    • one
      @romashechka however, this does not mean that your code is correct and does indeed what you need. - a_gura
    • one
     public class Client implements Runnable{ private static Lock lock = new ReentrantLock(); @Override public void run() { while (TestMultithreading.count <= 10) { lock.lock(); System.out.println(Thread.currentThread().getName() + " " + TestMultithreading.count); TestMultithreading.count++; lock.unlock(); } }