gpt4 book ai didi

java - 如何重新启动一个线程

转载 作者:行者123 更新时间:2023-11-30 05:58:11 27 4
gpt4 key购买 nike

我尝试编写一个文件监视器,如果附加了新行,它将检查文件,该监视器实际上是一个线程,它将始终通过随机访问文件读取该行。

这是监控核心代码:

public class Monitor {
public static Logger log = Logger.getLogger(Monitor.class);
public static final Monitor instance = new Monitor();
private static final ArrayList<Listener> registers = new ArrayList<Listener>();

private Runnable task = new MonitorTask();
private Thread monitorThread = new Thread(task);
private boolean beStart = true;

private static RandomAccessFile raf = null;
private File monitoredFile = null;
private long lastPos;

public void register(File f, Listener listener) {
this.monitoredFile = f;
registers.add(listener);
monitorThread.start();
}

public void replaceFile(File newFileToBeMonitored) {
this.monitoredFile = newFileToBeMonitored;

// here,how to restart the monitorThread?
}

private void setRandomFile() {
if (!monitoredFile.exists()) {
log.warn("File [" + monitoredFile.getAbsolutePath()
+ "] not exist,will try again after 30 seconds");
try {
Thread.sleep(30 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
setRandomFile();
return;
}
try {
if (raf != null) {
raf.close();
lastPos = 0;
}
raf = new RandomAccessFile(monitoredFile, "r");
log.info("monitor file " + monitoredFile.getAbsolutePath());
} catch (FileNotFoundException e) {
// The file must exist now
} catch (IOException e) {}
}

private void startRead() {
beStart = true;
String line;
while (beStart) {
try {
raf.seek(lastPos);
while ((line = raf.readLine()) != null) {
fireEvent(new FileEvent(monitoredFile.getAbsolutePath(),
line));
}
lastPos = raf.getFilePointer();
} catch (IOException e1) {}
}
}

private void stopRead() {
this.beStart = false;
}

private void fireEvent(FileEvent event) {
for (Listener lis : registers) {
lis.lineAppended(event);
}
}

private class MonitorTask implements Runnable {
@Override
public void run() {
stopRead();

//why putting the resetReandomAccessFile in this thread method is that it will sleep if the file not exist.
setRandomFile();
startRead();
}

}

}

这是一些帮助类:

public interface Listener {
void lineAppended(FileEvent event);
}


public class FileEvent {
private String line;
private String source;

public FileEvent(String filepath, String addedLine) {
this.line = addedLine;
this.source = filepath;
}
//getter and setter

}

这是调用监视器的示例:

public class Client implements Listener {
private static File f = new File("D:/ab.txt");

public static void main(String[] args) {
Monitor.instance.register(f, new Client());
System.out.println(" I am done in the main method");
try {
Thread.sleep(5000);
Monitor.instance.replaceFile(new File("D:/new.txt"));
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}

@Override
public void lineAppended(FileEvent event) {
String line = event.getLine();
if (line.length() <= 0)
return;
System.err.println("found in listener:" + line + ":" + line.length());
}
}

现在,我的问题是,如果我只是调用,代码就可以正常工作:

Monitor.instance.register(file,listener);

这将监视文件的行追加,并通知监听器。

但是当我调用时它不起作用:

Monitor.instance.replaceFile(anotherfile);

这意味着我想监视另一个文件而不是以前的文件。

所以在我的监视器中我必须重新启动线程,如何做到这一点?

我已经尝试过:

monitorThread.interruppt();

它不起作用。

任何人都可以帮我解决这个问题或告诉我该怎么做吗?

谢谢。

在我问之前,我已经谷歌搜索了“重新启动java线程”,所以我知道不能重新启动死线程,但是我的线程没有返回,所以我认为它可以重新启动。

最佳答案

您不必重新启动线程,而是在每次要启动线程时创建一个新线程。

更好的选择可能是使用 Executors.newCachedThreadPool(),它为您提供一个将为您启动/回收的线程池。

顺便说一句:您正在使用递归而不是循环来轮询文件是否存在。使用递归可能意味着如果等待太久就会抛出 StackOverflowError。恕我直言,您根本不应该等待,轮询线程应该重复尝试打开文件,直到被告知停止(或文件出现)

您当前的实现还意味着,如果文件被替换,您无论如何都必须在后台线程中重新打开该文件。

关于java - 如何重新启动一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4602758/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com