forJ
forJ

Reputation: 4627

Using executors and synchronizing CountDownLatch in different classes

Hi guys I was following a tutorial and I am curious about a few things that I tried applying my knowledge acquired from tutorial.

The below is a Runner class

package Tutorial2;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Runner {

    public void runIt() {

        CountDownLatch latch = new CountDownLatch (6);
        ExecutorService executor = Executors.newFixedThreadPool(2);

        for (int i = 0; i < 10; i++) {
            executor.submit(new Process(i, latch));
        }

        ExecutorService executor2 = Executors.newFixedThreadPool(2);

        for (int i = 1000; i < 1010; i++) {
            executor2.submit(new Process(i, latch));
        }

        try {
            latch.await();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("Program Ended");
   }
}

Then below is my Processor class

package Tutorial2;

import java.util.concurrent.CountDownLatch;

public class Process implements Runnable {

    private int id;
    CountDownLatch latch = new CountDownLatch(6);

    public Process(int id, CountDownLatch latch) {
        this.id = id;
        this.latch = latch;
    }

    @Override
    public void run() {
        System.out.println("Task Starting ID : " + id);

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("Task Finished ID : " + id);
        latch.countDown();
    }
}

It's pretty simple what I am trying to do. So there are a few questions that I wanna ask you professionals. So I understand that CountDownLatch counts down by one whenever .countDown is called. Then .await will return if the countdown is zero.

What I am curious about is that the CountDownLatch in Runner class and CountDownLatch in Process class should be different but reaching zero in CountDownLatch of Process class also seems to trigger .await which I put in Runner class. How does this work when I am only passing CountDownLatch as a parameter into Process class and no value of CountDownLatch from Process class is returned back to Runner class?

Also, below, I set up two Executors so that each executor will countdown the CountDownLatch but I seem to be getting more number of threads being processed than the number I input (6) before it is returned. What am I doing wrong? How would I make it so that "Program Ended" is printed when CountDownLatch reaches 0 i.e. threads have been run 6 times in total from both the executors.

Upvotes: 0

Views: 1206

Answers (2)

Solomon Slow
Solomon Slow

Reputation: 27210

I made int countDown in one class and made same int countDown in another class. In one class, I made a constructor to pass countDown from another class which I made this.countDown = countDown to make sure they refer to same variables. Then I ... but the countDown from two classes do not point to the same value.

A variable is not a thing that anything else in Java can "refer to." A variable is a named location that can hold a value.

All values in Java fall into either one of two categories; Object references, and primitive values. An Object reference is a pointer to an object on the Java heap. A primitive value basically is just a number, like 5. 5 is a primitive value of type int.


When your program executes this.countDown = countDown, That does not establish any relationship between the two variables. All it does is set this.countDown equal to whatever value happened to be in countDown at that particular moment in time. If the program subsequently changes either this.countDown or countDown, that has no effect on the other variable.

In some programming languages, you can create an alias---a thing that looks like a unique variable, but which actually is a reference to some other variable---but you can never do that in Java.

Upvotes: 2

kan
kan

Reputation: 28991

By this.latch = latch; you overwrite object's reference with the one which passed in the constructor argument (i.e. the one which created in the runIt method). The assignment CountDownLatch latch = new CountDownLatch(6); in Process class is useless, it does nothing. Just confuses you.

Second question is unclear... Yes, as soon it counted down to zero, it releases await... Not sure how it is related to how much threads/executors you have.

Upvotes: 2

Related Questions