If I do not synchronize the methods, what is happening in the background which is causing the app to run while console prints nothing?

Viewed 57

I have a main class which has two threads. These two threads runs two methods defined in other class.

WaitNotifyMain.java

package com.practice.multithreading;

public class WaitNotifyMain {

    public static void main(String[] args) {
        WaitNotify waitNotify = new WaitNotify();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    waitNotify.produce();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        // lambda expressions Java 8
        Thread t2 = new Thread(() -> {
            try {
                waitNotify.consume();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

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

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }

}

WaitNotify.java

package com.practice.multithreading;

import java.util.LinkedList;
import java.util.List;

public class WaitNotify {


    /*created an object of linkedlist without Polymorphism  as we require 
    removeFIrst() method which is specific to the linkedList class*/
    private LinkedList<Integer> list = new LinkedList<Integer>();

    private final int LIMIT=10;

    public void produce() throws InterruptedException{
        int value = 0;
        while(true) {

            while(list.size()!=LIMIT) {
            list.add(value++);
            System.out.println("Added an element");

            }

        }

    }

    public void consume() throws InterruptedException{

        while(true) {
            while(!list.isEmpty()) {
                System.out.print("List size :"+list.size());
                int value = list.removeFirst();
                System.out.println("; value is: " +value);

            }

        }
    }
}

Output

Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
List size :1Added an element
; value is: 0
List size :10Added an element
; value is: 1
List size :10Added an element
; value is: 2
List size :10Added an element
; value is: 3
List size :10Added an element
; value is: 4
List size :10Added an element
; value is: 5
List size :10Added an element
; value is: 6
List size :10Added an element
; value is: 7
List size :10Added an element
; value is: 8
List size :10Added an element
; value is: 9
List size :10Added an element
; value is: 10
List size :10Added an element
; value is: 11
List size :10Added an element
; value is: 12
List size :10; value is: 13
List size :10; value is: 14
List size :9; value is: 15
List size :8; value is: 16
List size :7; value is: 17
List size :6; value is: 18
List size :5; value is: 19
List size :4Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
; value is: 20
List size :10; value is: 21
List size :10; value is: 22
List size :9; value is: 23
List size :8; value is: 24
List size :7; value is: 25
List size :6; value is: 26
List size :5; value is: 27
List size :4; value is: 28
List size :3; value is: 29
List size :2; value is: 30
List size :1; value is: 31
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
Added an element
List size :1Added an element
; value is: 32
List size :10Added an element
; value is: 33
List size :10Added an element
; value is: 34
List size :10Added an element
; value is: 35
List size :10Added an element
; value is: 36
List size :10; value is: 37
List size :10Added an element
Added an element
; value is: 38
List size :10Added an element
; value is: 39
List size :10Added an element
; value is: 40
List size :10Added an element
; value is: 41
List size :10Added an element
; value is: 42
List size :10Added an element
; value is: 43
List size :10Added an element
; value is: 44
List size :10Added an element
; value is: 45
List size :10Added an element
; value is: 46
List size :10Added an element
; value is: 47
List size :10Added an element
; value is: 48
List size :10Added an element
; value is: 49
List size :10Added an element
; value is: 50
List size :10Added an element
; value is: 51
List size :10Added an element
; value is: 52
List size :10Added an element
; value is: 53
List size :10Added an element
; value is: 54
List size :10Added an element
; value is: 55
List size :10Added an element
; value is: 56
List size :10Added an element
; value is: 57
List size :10Added an element
; value is: 58
List size :10Added an element
; value is: 59
List size :10Added an element
; value is: 60
List size :10Added an element
; value is: 61
List size :10Added an element
; value is: 62
List size :10Added an element
; value is: 63
List size :10Added an element
; value is: 64
List size :10Added an element
; value is: 65
List size :10Added an element
; value is: 66
List size :10Added an element
; value is: 67
List size :10Added an element
; value is: 68
List size :10Added an element
; value is: 69
List size :10Added an element
; value is: 70
List size :10Added an element
; value is: 71
List size :10Added an element
; value is: 72
List size :10Added an element
; value is: 73
List size :10Added an element
; value is: 74
List size :10Added an element
; value is: 75
List size :10Added an element
; value is: 76
List size :10Added an element
; value is: 77
List size :10Added an element
; value is: 78
List size :10Added an element
; value is: 79
List size :10Added an element
; value is: 80
List size :10Added an element
; value is: 81
List size :10Added an element
; value is: 82
List size :10Added an element
; value is: 83
List size :10Added an element
; value is: 84
List size :10Added an element
; value is: 85
List size :10Added an element
; value is: 86
List size :10Added an element
; value is: 87
List size :10Added an element
; value is: 88
List size :10Added an element
; value is: 89
List size :10Added an element
; value is: 90
List size :10Added an element
; value is: 91
List size :10Added an element
; value is: 92
List size :10Added an element
; value is: 93
List size :10Added an element
; value is: 94
List size :10Added an element
; value is: 95
List size :10; value is: 96
List size :10; value is: 97
List size :9; value is: 98
List size :8; value is: 99
List size :7Added an element
Added an element
Added an element
Added an element
Added an element
; value is: 100
List size :10; value is: 101
List size :9; value is: 102
List size :8; value is: 103
List size :7; value is: 104
List size :6; value is: 105
List size :5; value is: 106
List size :4; value is: 107
List size :3; value is: 108
List size :2; value is: 109
List size :1; value is: 110

>>>>>>>after this nothing in console<<<<<<<<<<<<<

I understand that as it is not being synchronized it is not working as expected and i am getting diff outputs each time i run.

But my question is why the console shows my app is till running ,while i do not see any output in the console.

Can someone explain this behavior?

I have tried out few more things, if put Thread.sleep() inside the outer loops then it keeps on printing in the console infinitely, and if i put syso in the outside loops then also i get output in the console indefinitely.

What is this weird behavior.

2 Answers

Add output in both while(true) loops, and you will see that one of the threads is stucked, probably the other thread is not getting the quantum time.

The JVM will, at some point, cache the size of the list - which is the basis for list.size() and list.isEmpty() - in each thread, for as long as it can.

Without any synchronized block, "as long as it can" will be indefinitely.

If the producer is not synchronized, at some point it will cache list.size() == 10, and won't enter the inner loop, and won't produce any new values for the consumer to consume.

If the consumer is not synchronized, at some point it will cache list.size() == 0, and won't enter the inner loop, and won't clear space from the list to allow the producer to produce.

So in fact, you will get this hang even if you synchronized only the producer or only the consumer.

When you add something like Thread.sleep() or System.out.println(), you're asking the JVM to perform an operation that's essentially "external", which causes the JVM to refresh its cached values for this thread.

Related