0

I have a utility class which starts a long running background thread. The utility class is initialized in main class. But utility class object is getting garbage collected. How can i prevent that. Here is my class structure.

public class Main {

public static void main(String[] args) throws Exception {
  Utility u = new Utility();
  u.startTask(); //This is not referenced after this and hence getting gc'ed
  .....
  ....
  api.addMessageCreateListener(event -> {
  /////continuously running 
  }
 }
}

What i want is to prevent Utility object from getting garbage collected.

Shekhar
  • 55
  • 6
  • 4
    Why do you want to prevent gargabe collection if no code uses it? – plalx Jun 25 '20 at 19:22
  • @plalx is right: It suggests there is problem with the design if there exists no references to an instance but breaks your application if the GC collects it. Please give us some more information about what you are trying to achieve. – ToxicWaste Jun 25 '20 at 19:37
  • Presumably, it runs a task in the background, in which case it should be in a new thread – user Jun 25 '20 at 19:46
  • u.startTask() is starting a long running background thread which refreshes a local cache. – Shekhar Jun 25 '20 at 20:09
  • Why? How does it affect your application that it gets GC'd? How can you even tell? And how does 'starting a long running background thread which refreshes a local cache' answer the question? – user207421 Jun 26 '20 at 00:30
  • 2
    You still didn’t answer why you want to prevent the garbage collection of the `Utility` instance. What is the assumed relevance of its garbage collection? Why do you think, it imposes a problem? – Holger Jun 26 '20 at 13:04

1 Answers1

1

I assume the Method Utility#startTask() starts Threads on its own, otherwise this would be a blocking call and the main-Method would not end before startTask returned.

However this should not stop you from implementing the Runnable Interface in Utility itself. As long as the Utility runs in its own Thread, you do not need to worry about the enclosing method returning. Since the Tread is still running, the Instance will not be collected.

public class Threading {

    public static void main(String[] args) {
        Utility utility = new Threading().new Utility();
        Future utilFuture = Executors.newSingleThreadExecutor().submit(utility);

        System.out.println("end main");
    }
    
    public class Utility implements Runnable {
        @Override
        public void run() {
            System.out.println("Start Utility");
            for(int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(1000);
                    System.out.println("foo: " + i);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                }
            }
        }
        
    }
}

Note: In your case you might not need the Future, but it is an extremely useful tool to interrupt the Execution if needed.

ToxicWaste
  • 135
  • 1
  • 7