如何使用线程观察器

时间:2015-04-28 19:52:15

标签: java multithreading

正在处理我们遇到线程问题的项目。有一个问题使线程终止,并且线程无法自动重启,因此我们想要更改当前的实现。 我们提出了运行一个观察者线程来管理文件处理线程的想法 有人可以建议如何制作观看节目状态的线索以及如何做到这一点的想法。

编辑:所以基本上这就是发生的事情。用户上载一些写入文件共享的媒体文件。在移动服务中运行的线程扫描媒体文件并附加到电子邮件。在此过程中,线程终止,并且无法将媒体附加到电子邮件中。

以下是我的servlet和run方法的代码。

private synchronized void startProcessing() {
    boolean processor = false;
    try {
        Properties mProp = SystemUtil.filterProperties(SystemImpl.getInstance().getApplicationProperties("Media"));
        processor = (Boolean.parseBoolean(mProp.getProperty("processor", "false")) && Boolean.parseBoolean(System.getProperty("RunProcessor", "false")));
    } catch (Exception e) {
        logger.log(Level.INFO, "Unable to get 'processor' value from property file.  Defaulting to false.");
    }
    if (processor) {
        if (null != thread) {
            if (thread.getState().equals(State.TERMINATED)) {
                thread = new Thread(fProc);
            }
        } else {
            thread = new Thread(fProc);
        }
        if (thread.getState().equals(State.NEW)) {
            logger.log(Level.INFO, "processor starting...");
            thread = new Thread(fProc);
            thread.start();
            logger.log(Level.INFO, "processor successfully started.");
        } else {
            logger.log(Level.INFO, "processor thread is already running.");
        }
    } else {
        logger.log(Level.INFO, "processor configured not to run.");
    }
}

public void run() {
    int sleepTime = 10000;
    try {
        sleepTime = Integer.parseInt(mProp.getProperty("ProcessorSleepTime"));
        waitTime = -(Integer.parseInt(mProp.getProperty("ProcessorWaitTime")));
        keepProcessed = Boolean.parseBoolean(mProp.getProperty("KeepProcessed"));
    } catch (Exception ex) {
        logger.log(Level.WARNING, "Unable to read property file.  Using default values.");
    }
    File filePath = new File(MResource.getMRepositoryPath());
    File processingPath = new File(filePath.getPath() + "/" + PROCESS_FOLDER_NAME);
    if (!processingPath.exists()) {
        processingPath.mkdirs();
    }
    File failurePath = new File(filePath.getPath() + "/" + FAILURE_FOLDER_NAME);
    if (!failurePath.exists()) {
        failurePath.mkdirs();
    }
    File processedPath = new File(filePath.getPath() + "/" + PROCESSED_FOLDER_NAME);
    if (!processedPath.exists()) {
        processedPath.mkdirs();
    }
    while (!stopProcessing) {
        isProcessing = true;
        logger.log(Level.FINEST, "Checking for files...");
        try {
            processFiles(filePath, processingPath, failurePath, processedPath);
            try {
                Thread.sleep(sleepTime);
            } catch (InterruptedException e) {
                logger.log(Level.INFO, "Thread sleep interrupted.");
            }
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Error while processing files.", e);
        }
    }
    isProcessing = false;
    stopProcessing = false;
    logger.log(Level.WARNING, " file processor has stopped.");
}

2 个答案:

答案 0 :(得分:1)

我认为修复原因要比重新启动它更容易。 终止线程的方法只有两种:

  1. 调用thread.stop()。这已被弃用,99.9%不是你的情况
  2. 通过正常终止或异常退出run()方法。用try {...} catch(Throwable)finally {}包装你的run方法,并在那里放一些日志,你会发现原因。
  3. 如果你真的需要观察者,你可以这样做:

    void run() {
        while (true) {
            thread.join();
            thread = new Thread(myRunnable);
            thread.start();
        }
    }
    

答案 1 :(得分:0)

你绝对不应该终止该线程。也许你应该让线程等待。要重新启动线程,您需要在终止时知道它的确切状态。您必须保存该线程的状态,然后完美地重建正确的线程。所以你第一个问题可能是"我该怎么做"。如果不知道你的程序内部和外部,它是不可能告诉你的。但这应该是绝对的最后手段。因为在几乎每种情况下它都是一个非常可怕的想法。(预计会出现比你能处理的更多的错误)

TLDR;

这是一个坏主意。不要终止该线程。

编辑:嗯,我想你必须找到首先杀死线程的错误。如果你没有找到,那么你无法在它死之前保存线程的状态。您可以尝试使用print语句或调试器