Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing variable in a thread java

I have one global variable in my thread class, which is an ArrayList<>. I am running this thread periodically from the main() method; whenever this thread runs, I am populating this list in a run() method. I want to access this list from my main() method, but whenever I access this list from main(), I get an empty list. Please suggest how can I achieve this, following is my code example.

private static ArrayList<SampleClass> allproxyDetailsPojoList = null;   

public static void main(String[] args) {
    try {
        ScheduledExecutorService threadSchedulerService = Executors.newScheduledThreadPool(1);
        threadSchedulerService.scheduleAtFixedRate(new SampleThreadClass(), 0, 5, TimeUnit.MINUTES);

        Thread.sleep(8000);

        SampleThreadClass sampleThreadClass = new SampleThreadClass();

        // here i am getting list empty
        allproxyDetailsPojoList = sampleThreadClass.getSampleClassList();

    } catch (Exception e) {

    }
}

and this is my thread class,

public class SampleThreadClass implements Runnable {

    ArrayList<SampleClass> sampleClassList = null;

    @Override
    public void run() {
        MyDao myDao = null;
        try {
            myDao = new MyDao();
            sampleClassList = myDao.getSampleClassList();
        } catch (Exception e) {

        }
    }

    public ArrayList<SampleClass> getSampleClassList(){
        return sampleClassList;
    }
}

Note : can not use the static keyword.

like image 778
Tushar Deshpande Avatar asked Jul 02 '26 09:07

Tushar Deshpande


1 Answers

You need to understand what instances of a class are in contrast of the class definition. In your code you create two instances of the class. Since the variable is not static, each of the instances has its own instance of that variable. You cannot acces instance 1's variable through instance 2's reference.

try {
    ScheduledExecutorService threadSchedulerService = Executors.newScheduledThreadPool(1);
    threadSchedulerService.scheduleAtFixedRate(new SampleThreadClass(), 0, 5, TimeUnit.MINUTES);
                                           //  ^ 1st Instance
    Thread.sleep(8000);

    SampleThreadClass sampleThreadClass = new SampleThreadClass(); // <-- 2nd Instance

So to use one single instance, change this to

try {
    ScheduledExecutorService threadSchedulerService = Executors.newScheduledThreadPool(1);

    SampleThreadClass sampleThreadClass = new SampleThreadClass();
    threadSchedulerService.scheduleAtFixedRate(sampleThreadClass , 0, 5, TimeUnit.MINUTES);

    Thread.sleep(8000);

But to avoid "strange behavior", I'd also synchronize access to sampleClassList.

Also, to avoid NPEs I'd change

public ArrayList<SampleClass> getSampleClassList(){
    return sampleClassList;
}

to

public ArrayList<SampleClass> getSampleClassList(){
    if ( null != sampleClassList )
        return sampleClassList;
    return Collections.emptyList();
}

But mind that this empty list is immutable. If you need a mutable list, you could just return a new ArrayList<SampleClass>().

P.S.

Using a sleep is not really making this code stable. If you expect a list actually being present after having waited for the service call to be executed at least once, you should do so and not wait for a fixed time period. But that would be another question.

like image 80
Fildor Avatar answered Jul 03 '26 21:07

Fildor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!