Java 计时器任务的意外行为

Unexpected behaviour with Java timer task

我的计时器任务没有按预期运行。我已安排它每 3 秒重复一次特定任务,但这并没有发生。

根据 Java 文档:

schedule(TimerTask task, long delay,long period) . Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals separated by the specified period.

public class Tester {

    public static void main(String[] args) {    
        log.info("Schedule task");
        Timer time = new Timer();

        TesterClient tc = new TesterClient();
        time.schedule(tc, 0, 3000);
    }
}


public class TesterClient extends TimerTask {
    public void init() {
        System.out.println("New Task!!!!");
    }
    @Override
    public void run() {
        init();
    }
}

但我只在控制台

中打印了一个 "New Task!!!!"

我是不是遗漏了什么?

谢谢

更新:

我将尝试在此处粘贴每段相关的代码,并从上到下执行。

开始:

public class Tester {

    public static Logger log = Logger.getLogger("com.orderlysoftware.orderlycalls.manager.ManagerClient");
    public static Timer time = new Timer();

    public static void main(String[] args) {            
        log.info("Creating service");
        Service.serviceInit();  

        log.info("Initializing TesterClient for scheduled task");
        TesterClient tc = new TesterClient();
        time.schedule(tc, 0, 3000);
    }
    public static ManagerSettings managerSettings() {
        ManagerSettings managerSettings = new ManagerSettings();
        managerSettings.setName("managerClient");
        managerSettings.setHost("77.237.251.152");
        managerSettings.setPort(5038);
        managerSettings.setUsername("orderlystats");
        managerSettings.setPassword("orderlystats");

        return managerSettings;
    }   
}

Service class method:

static ExecutorService executorService; 
    {
        serviceInit();
    }

    //public static ClassLoader loader;

    public static void serviceInit(){
        if(executorService!=null) {
            return;
        }
        executorService= Executors.newCachedThreadPool();
        try {
            ThreadPoolExecutor tpe=(ThreadPoolExecutor)executorService;
            tpe.setMaximumPoolSize(100000);
        } catch (Exception ex) {
            System.out.println(ex);
        }
    }

package com.orderlysoftware.testing;

import java.io.IOException;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.logging.Logger;

import com.orderlysoftware.orderlycalls.OrderlyCalls;
import com.orderlysoftware.orderlycalls.asterisk.manager.ManagerClient;
import com.orderlysoftware.orderlycalls.asterisk.manager.action.ManagerResponse;
import com.orderlysoftware.orderlycalls.asterisk.manager.event.ManagerEvent;
import com.orderlysoftware.orderlycalls.asterisk.manager.event.ManagerEventListener;
import com.orderlysoftware.orderlycalls.base.Service;

public class TesterClient extends TimerTask {

    public static Logger log = Logger.getLogger("com.orderlysoftware.orderlycalls.manager.ManagerClient");
    public static ExecutorService es = Service.getExecutorService();

    public ManagerClient mc;

    public void init() {    
        log.info("run check method to see if Manager Client is running");
        boolean running = check();

        log.info("checker status is : " + running);
        while(running) {
            try {
                Thread.sleep(3000);
                startCall();
            } catch (InterruptedException e) {
                log.info("Sleep interrupted");
            }
        }   
    }
    public boolean check() {
        log.info("ManagerClient is: " + mc);
        if(mc == null) {
            log.info("Initialize service");
            mc = (ManagerClient)OrderlyCalls.createService(ManagerClient.class, Tester.managerSettings());
            log.info("Initialize ManagerClient");
            mc.init();
            log.info("Service created. ManagerClient initialized : "+ mc);
        }
        if(!mc.isConnected()) {
            log.info("ManagerClient is not connected");         
            return false;
        }
        log.info("Check if ManagerClient is connected AND running");
        if(mc.isConnected() && !mc.isRunning()) {
            log.info("Manager Client is connected but NOT running");
            return false;
        }
        if(mc.isConnected() && mc.isRunning()) {
            log.info("ManagerClient is connected and running");
            return true;
        }
        return false;
    }
    private void startCall() {
        log.info("Adding listener to the call");
        addListenerToCall(mc);

        int testID = 0;
        ManagerResponse response = null;
        try {
            response = mc.originate("Local/1001@main", "1001", "main", "1", null, null, 2500, "1002", "testID=" + (testID++), "1", true);
            log.info("Manager response is: " + response);
            if(response == null) {
                mc.shutdown();
                throw new IOException("Null response for originate.");              
            }
            if(!response.getValue("Response").equals("Success")) {
                mc.shutdown();
                throw new IOException("Originate returned " + response.getValue("Response") + ": " + response.getValue("Message"));
            }
        } catch (IOException e) {
            log.info("IO Exception" + e.toString());
        }
    }   
    public void addListenerToCall(ManagerClient mc) {       
        try {
            // Add event listener 
            log.info("Adding ManagerEventListener to ManagerClient: " + mc);
            mc.addManagerEventListener(new ManagerEventListener() {         
                @Override
                public void handleManagerEvent(ManagerEvent event) {
                    if("OriginateResponse".equals(event.getType())) {
                        handleOriginateResponse(event);
                    }
                }
            });
        } catch (IOException e) {
            log.info("IO Exception : " + e);
        }       
    }
    protected void handleOriginateResponse(ManagerEvent event) {
        try {
            // do something here 
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            log.info("sleep interupted" + e);
        }           
    }

    @Override
    public void run() {
        log.info("New Task!!!!!!!!!!");
        init(); 
    }   
}

它对我有用 - 但我怀疑问题是你让 Timer 收集垃圾:

After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection). However, this can take arbitrarily long to occur.

如评论中所述,我相信 "outstanding tasks" 意味着 "tasks that have already been started" 而不仅仅是 "ones which would be scheduled"。但是,文档不清楚,我可能弄错了。

如果你阻止垃圾收集(例如通过在静态变量中保留对 Timer 的引用)那么我想你会看到它永远持续下去......

你的程序对我来说也很好用。在您的程序中进行以下更改后问题重现:

import java.util.*;
public class Tester {

    public static void main(String[] args) {
        System.out.println("Schedule task");
        Timer time = new Timer();

        TesterClient tc = new TesterClient();
        time.schedule(tc, 0, 3000);
    }
}


class TesterClient extends TimerTask {
    public void init() {
        System.out.println("New Task!!!!");
    }
    @Override
    public void run() {
        init();
        this.cancel(); //-------This causes hang in execution after printing once
    }
}

但是,如果您的程序中没有 cancel(),我不确定是什么导致了这种情况发生。