Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 974393
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 16, 20262026-05-16T03:25:49+00:00 2026-05-16T03:25:49+00:00

I have an object that needs to do periodically do some work while the

  • 0

I have an object that needs to do periodically do some work while the object itself is alive, so I designed something like the following. Basically a Main class which contains a reference to a ScheduledExecutorService instance. In this example, all the periodical work is to print a string to std.

I expect the code to behave like the following:

  1. test2 gets called, which create a Main object o1 (within it a ScheduledExecutorService).
  2. test2 register to print out a line every second on o1.
  3. test2 returns, o1 becomes garbage.
  4. System gc kicks in to gc o1, which has a finalize method to shutdown it’s local scheduler.

However, if I run this program, what happens is that it will go on FOREVER. Basically the gc never calls o1’s finalizer and as a result, scheduler never shuts down and as a result, even when main thread end, the program still won’t quit.

Now if I comment out the o1.register in test2(), the program behaves like it should, e.g. gc called etc. Also in debugger it seems only after a call to ScheduledExecutorService.schedule will an actual thread created.

Any explanation what’s happening?

public class Main {

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

    System.gc();
    System.out.println("Waiting for finalize to be called..");
    Thread.sleep(5000);
}

private static void test2() throws Exception {
    Main o1 = new Main();
    o1.register();
    Thread.sleep(5000);     
}

private final ScheduledExecutorService _scheduler = Executors.newSingleThreadScheduledExecutor();   

private void register() {
    _scheduler.scheduleWithFixedDelay(new Runnable() { 
        @Override public void run() { 
            System.out.println("!doing stuff...");
            }
        }, 1, 1, TimeUnit.SECONDS);
}

@Override
protected void finalize() throws Throwable  {
    try {
        System.out.print("bye");
        _scheduler.shutdown();          
    } finally {
        super.finalize();
    }       
}

}

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-16T03:25:49+00:00Added an answer on May 16, 2026 at 3:25 am

    After playing with WeakReference and ScheduledExecutorService, I think I have a better understanding of the problem now. The central problem in my code is the following method register(). It uses an anonymous object Runnable. The problem with anonymous object like this is it creates a strong reference back to the parent scope. Remember if you make fields in parent scope “final”, you can reference to them from within run() method of Runnable. I thought I do not create such strong ref if I don’t reference anything from my run(). As shown in this case, all I do in the run() is to print some static string out. However, according the the behavior observed, such reference is created nonetheless.

    private void register() {
    _scheduler.scheduleWithFixedDelay(new Runnable() { 
        @Override public void run() { 
            System.out.println("!doing stuff...");
            }
        }, 1, 1, TimeUnit.SECONDS);
    

    }

    The correct way of doing this kind of programming is to create a class and pass in your object yourself. You also need to keep only a weak reference. The code is rather long, I’ll just post the Runnable implementation, which keeps a weak reference to the domain object Main.

    private static class ResourceRefreshRunner implements Runnable
    {
        WeakReference<Main> _weakRef;
        public ResourceRefreshRunner(Main o)
        {
            _weakRef = new WeakReference<Main>(o);
        }       
        @Override
        public void run() { 
            try {
                Main m = _weakRef.get();
                if (m != null) 
                    m.shout(); 
                else 
                    System.out.println("object not there, but future is running. ");
            } catch (Exception ex) {
                System.out.println(ex.toString());
            }
        }
    }
    

    Now in the Main class, I have:

    public class Main {
    ScheduledExecutorService _poolInstance;
    ScheduledFuture<?> _future;
    public Main(ScheduledExecutorService p)
    {
        _poolInstance = p;
        _future = _poolInstance.scheduleWithFixedDelay(new ResourceRefreshRunner(this), 1, 1, TimeUnit.SECONDS);
    }  ...
    

    And the finalizer of Main:

        @Override
    protected void finalize() throws Throwable  {
        try {
            System.out.println("bye");
            _future.cancel(true);
        } finally {
            super.finalize();
        }       
    }
    

    With this setup, the code behaves as expected. E.g. when a Main object is no longer referenced, GC will kick in and the finalizer will get called. One more experiment I did is that without _future.cancel(true); in the finalize(), when the Main object is GC-ed, the weak reference in the Runnable.run() can’t dereference to a Main object anymore, but the thread and tasks is still running.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 480k
  • Answers 480k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer I've tried to do this once upon a time and… May 16, 2026 at 6:04 am
  • Editorial Team
    Editorial Team added an answer I have used the components mxExport from Max. It's free… May 16, 2026 at 6:04 am
  • Editorial Team
    Editorial Team added an answer Without knowing the HTML, you can use :first-child like this:… May 16, 2026 at 6:04 am

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.