gpt4 book ai didi

java - 阻塞线程运行 SAX 解析器

转载 作者:行者123 更新时间:2023-11-30 06:56:20 30 4
gpt4 key购买 nike

我在使用多线程来停止运行 SAX 解析器的应用程序时遇到问题。

我有一个类从 XML 文件逐行读取,我希望它能够在按下按钮时停止:

private String filename;
private boolean paused = false;

public xmlReader(String filename) {
this.filename = filename;
}

public void run() {
try {

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();

DefaultHandler handler = new DefaultHandler() {

// when an open row is encountered in the posts.xml file
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (!paused) {
System.out.println("Start Element :"
+ attributes.getValue("name"));
}

}
}
saxParser.parse (filename, handler);

这是读取 xml 文件的代码,但是由于我希望能够暂停和恢复 run 方法,所以我从线程调用它:

public class myThread implements Runnable {

private String file;
private TextArea Suggestions;
private volatile boolean running = true;
private volatile boolean paused = false;
databaseReader db = new databaseReader(this.file);

public void setSuggestions(TextArea Suggestions) {
this.Suggestions = Suggestions;
}

public void setFile(String dbFile) {
this.file = dbFile;
}

public void stop() {
running = false;
// you might also want to do this:
}

public void pause() {
// you may want to throw an IllegalStateException if !running
paused = true;
}

public void resume() {
synchronized (db) {
paused = false;
db.notifyAll(); // Unblocks thread
}
}

@Override
public void run() {
while (running) {
synchronized (db) {
db.run();
if (!running) {
break;
}
if (paused) {
try {
System.out.println("paused");
db.wait();
} catch (InterruptedException ex) {
break;
}
if (!running) {
break;
}
}
}
}
throw new UnsupportedOperationException("Not supported yet.");
//To change body of generated methods, choose Tools | Templates.
}

同样,我有一个按钮,按下时可以更改线程上 isRunning 的值:

 if (!isRunning) {
myThread search = new myThread();
search.start();
}

但是,这些似乎都没有停止线程,以至于即使在关闭应用程序后,线程仍然继续运行。

我尝试过的其他事情- 交换实现 Runnable 而不是扩展线程类并调用中断、wait()

  • 使用替代锁定系统,但它似乎并没有阻止我的 sax 解析器......

最佳答案

SAXParser 是一个基于事件的解析器 - 最古老且最不方便的 XML 解析器类型。正如您自己经历的那样,问题在于它完全控制了解析,而您只能使用react;你不能再行动了。

您有两个选择:

  1. 创建一个可停止的InputStream,以便您可以通过停止其输入来停止解析器。它可能仍然有一些缓冲数据,但很快就会停止。

  2. 改用流式解析器或 pull-parser 解析器(请参阅 example )。它不控制解析。相反,您驱动解析并请求下一个 XML 元素。当您掌控一切时,停止它是理所当然的。

选项 1 或多或少是这样工作的:

public class StoppedException extends RuntimeException {

}

public class StoppableInputStream extends InputStream {

private boolean stopped;
private InputStream wrappedStream;

public StoppableInputStream(InputStream wrapped) {
wrappedStream = wrapped;
}

public boolean isStopped() {
return stopped;
}

public void setStopped(boolean stopped) {
return this.stopped = stopped;
}

public int read() {
if (stopped)
throw new StoppedException();
return wrappedStream.read();
}

public int read(byte[] b) {
if (stopped)
throw new StoppedException();
return wrappedStream.read(b);
}

public int read(byte[] b, int off, int len) {
if (stopped)
throw new StoppedException();
return wrappedStream.read(b, off, len);
}

// do the same for all other methods of InputStream
}

然后像这样初始化解析器:

FileInputStream fis = new FileInputStream("yourfilename.xml");
StoppableInputStream sis = new StoppableInputStream(fis);
saxParser.parse (filename, handler);

最后,您可以像这样停止解析器:

sis.setStopped(true);

我还没有测试过代码。它甚至可能无法编译。

我建议您选择选项 2。

关于java - 阻塞线程运行 SAX 解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41729454/

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