Java: Why both threads are not running in parallel

I am trying to understand internal locks in java. I have a program in which I run 2 threads that will loop through and call synchronous methods on one object. I expect both threads to be running in parallel, but it looks like it is running in sequence.

If I enter a dream in a loop, they are executed in random order [as I expected]

public class Synchronized {

    private int valueM;

    public Synchronized( int value) {
        valueM = value;
    }

    synchronized
    public void one() throws InterruptedException
    {
        System.out.println("Object[" + valueM + "] executing one");
        Thread.sleep(100); //For case 2: comment it out
        System.out.println("Object[" + valueM + "] completed one");
    }

    synchronized
    public void two() throws InterruptedException
    {
        System.out.println("Object[" + valueM + "] executing two");
        Thread.sleep(100); //For case 2: comment it out
        System.out.println("Object[" + valueM + "] completed two");
    }

}

Test code:

@org.junit.jupiter.api.Test
    void test_sync() throws InterruptedException
    {
        Synchronized obj = new Synchronized(1);

        Runnable task_one = new Runnable() {
            public void run() {
                for (int i=0 ; i<10; i++)
                {
                    try {
                        obj.one();
                        //Thread.sleep(100); //For case 2: uncomment it out
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        };

        Runnable task_two = new Runnable() {
            public void run() {
                for (int i=0 ; i<10; i++)
                {
                    try {
                        obj.two();
                        //Thread.sleep(100); //For case 2: uncomment it out
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread t1 = new Thread(task_one);
        Thread t2 = new Thread(task_two);

        t1.start();
        t2.start();

        t1.join();
        t2.join();
    }

Conclusion:

Case 1: output:
Object[1] executing one
Object[1] completed one
...10times
Object[1] executing two
Object[1] completed two
...10times

Case 2: output: random order
Object[1] executing one
Object[1] completed one
Object[1] executing two
Object[1] completed two
...

UPDATE: The original problem has been fixed. It seems like this is a random case even in case 1, but I only see it when loading with a lot of iterations (30K).

, for ? - Java-JVM, for-loop " " ( , ?)?

+4
4

intrinsic ( synchronized) "", , , .

, , , , , .

, (), , ReentrantLock, , boolean, true

ReentrantLock(boolean fair)

class X {
  private final ReentrantLock lock = new ReentrantLock(true);

  public void m() {
    lock.lock(); 
    try {
      // method body
    } finally {
     lock.unlock()
   }
  }
}
+1

one two synchronized. , , , obj. , . one/two, , . , - , .

, . JVM, , .

0

, .

  • , synchronized ( synchronized).

  • 2 . .

  • : 1 sleep, , case 2 sleep, .

3. sleep . wait, , , . , .

, . - , , .

, , sleep , ? : , , , .

0

Thread # start - . 10 ( 1000) . , . "", .

Your test is also confused by the fact that, depending on the runtime, the author of the system script itself may be a synchronized disputed resource (or, conversely, it may not be guaranteed to be smoothed and recorded in an agreed way, exactly the order flows turned to it.) Trying to use System.out. println for debugging concurrency problems has caused many people to experience big problems over the years, because pausing to receive a console script usually hides a consistency error in memory.

public static CountDownLatch latch = new CountDownLatch(1);

public static class Thing implements Runnable {
    @Override
    public void run() {
        try {
            latch.await();
            //doStuff
        } catch (InterruptedException e) {

        }
    }
}
public static void main(String[] args) throws Exception {

    Thing thing1 = new Thing();
    Thing thing2 = new Thing();
    new Thread(thing1).start();
    new Thread(thing2).start();
    latch.countDown();
}
0
source

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


All Articles