gpt4 book ai didi

Java多线程解析器

转载 作者:行者123 更新时间:2023-12-03 05:59:26 25 4
gpt4 key购买 nike

我正在编写一个多线程解析器。解析器类如下。

public class Parser extends HTMLEditorKit.ParserCallback implements Runnable {

private static List<Station> itemList = Collections.synchronizedList(new ArrayList<Item>());
private boolean h2Tag = false;
private int count;
private static int threadCount = 0;

public static List<Item> parse() {
for (int i = 1; i <= 1000; i++) { //1000 of the same type of pages that need to parse

while (threadCount == 20) { //limit the number of simultaneous threads
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}

Thread thread = new Thread(new Parser());
thread.setName(Integer.toString(i));
threadCount++; //increase the number of working threads
thread.start();
}

return itemList;
}

public void run() {
//Here is a piece of code responsible for creating links based on
//the thread name and passed as a parameter remained i,
//connection, start parsing, etc.
//In general, nothing special. Therefore, I won't paste it here.

threadCount--; //reduce the number of running threads when current stops
}

private static void addItem(Item item) {
itenList.add(item);
}

//This method retrieves the necessary information after the H2 tag is detected
@Override
public void handleText(char[] data, int pos) {
if (h2Tag) {
String itemName = new String(data).trim();

//Item - the item on which we receive information from a Web page
Item item = new Item();
item.setName(itemName);
item.setId(count);
addItem(item);

//Display information about an item in the console
System.out.println(count + " = " + itemName);
}
}

@Override
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
if (HTML.Tag.H2 == t) {
h2Tag = true;
}
}

@Override
public void handleEndTag(HTML.Tag t, int pos) {
if (HTML.Tag.H2 == t) {
h2Tag = false;
}
}
}

从另一个类解析器运行如下:

List<Item> list = Parser.parse();

一切都很好,但有一个问题。解析结束时,最终列表“List itemList”包含 980 个元素,而不是 1000 个。但在控制台中,共有 1000 个元素(项目)。即某些线程由于某种原因没有调用handleText方法中的addItem方法。

我已经尝试将 itemList 的类型更改为 ArrayList、CopyOnWriteArrayList、Vector。使方法 addItem 同步,更改其对同步块(synchronized block)的调用。这一切只是改变了一点元素的数量,但最终无法获得一千个。

我还尝试解析较少数量的页面(十)。结果列表是空的,但在控制台中都是 10。

如果我删除多线程,那么一切都会正常工作,但是当然会很慢。这可不好。

如果减少并发线程数,列表中的项目数接近所需的 1000,如果增加,则与 1000 有点距离。也就是说,我认为,记录到的能力存在困难。列表。但是为什么同步不起作用呢?

有什么问题吗?

最佳答案

在您的 parse() 调用返回后,所有 1000 个线程都已启动,但不能保证它们都已完成。事实上,它们并不是你所看到的问题。我强烈建议不要自己编写此内容,而是使用 SDK 为此类工作提供的工具。

文档 Thread PoolsThreadPoolExecutor例如一个好的起点。再次强调,如果您不确定自己是否也实现了这一点,请不要自己实现它,因为编写这样的多线程代码纯粹是痛苦的。

您的代码应如下所示:

ExecutorService executor = Executors.newFixedThreadPool(20);
List<Future<?>> futures = new ArrayList<Future<?>>(1000);
for (int i = 0; i < 1000; i++) {
futures.add(executor.submit(new Runnable() {...}));
}
for (Future<?> f : futures) {
f.get();
}

关于Java多线程解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7785839/

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