gpt4 book ai didi

java - 如何以正确的方式动态处理开始和结束线程和信息?

转载 作者:太空宇宙 更新时间:2023-11-04 11:49:42 25 4
gpt4 key购买 nike

我无法找到适用于我的问题的答案,希望我能在这里找到可以为我指明正确方向的人。

我试图让程序动态创建类实例和线程,并处理结束它们,并在允许更多实例和线程启动之前清除内存。

我正在编写的程序涉及访问大量设备,有时是定期访问。我需要一种适当的方法来跟踪线程、哪个用户命令启动了它们,并将它们排队,这样它们就不会溢出内存。

用户可以选择结束可能包含许多线程的任务,因此我需要能够全面终止该组。

我认为 Arraylist 是最好的,但如下所示,我需要 3 个列表才能协同工作,分别用于名称、类实例和线程。

public Class implements Runnable {

private inner class doThings implements Runnable {

public bool active = true

public bool done(){
return true;
}

public run() {
while (active){
x=1+1
}
public void instakill(){
active = false;
}
}

public void mainLoop() {

int maxThreads = 50

List names;
List instances;
List threads;

while true {

for (each request) {

if (threads.size < maxThreads ) {

names.add("unique name")
instances.add(new doThings())
threads.add(new Thread(instances.size - 1))

threads.get(Threads.size - 1).start

}
}

for (each instance) {

if (doThings.done()){

int arrayID = instance.getIndex

names.remove(arrayID)
instances.remove(arrayID)
threads.remove(arrayID)

trim-All-Lists-To-Size();

}

}

}

因此,主循环将创建 doThings 类的新实例,以及唯一的名称和运行该类的线程。它们被放入单独的、未链接的数组中。我匹配它们的唯一方法是获取一个数组中的任何索引,并计算出由于我以统一方式从所有数组中添加和主题,所以它应该是相同的索引。有点像分别装满三杯水,并期望它们处于同一水位。

当然,事实并非如此。

如果我知道如何组合 3 位信息(名称、实例、线程),我可能就不会遇到这个问题了,不是吗?

我应该将所有内容封装到一个更大的类中并保留其中的 ArrayLists (或 CopyOnWriteArrayLists )吗?

我不确定解决这个问题的正确方法是什么

感谢您的帮助!!

最佳答案

根据 Peter 的建议,您应该明确考虑使用 ExecutorService而不是基于线程管理开发类似的API机制。

不过,关于你的原始代码,我认为你的困难实际上与线程管理无关,而只是与Java中的数据结构有关。最常见的方法不是并行维护三个不同的列表,而是简单地将三个信息封装在某个内部类的实例中(例如 Entry ),然后拥有一个包含这些 Entry 的列表。 (即,在现代 Java 中: List<Entry> )。

另一件需要知道的事情是,在迭代集合时,永远不应该删除集合中的元素,除非使用迭代器的删除方法;如果你这样做,你最终会得到 ConcurentModificationException 。正确的方法是在集合上显式创建一个迭代器(例如 list.iterator() ),然后对其进行迭代(使用 iterator.hasNext()iterator.next() ),最后使用 `iterator.remove() 删除元素。

例如,您的代码可能如下所示:

public class ParentClass {

private class RunningInstanceEntry {
public String name;
public Worker worker;
public Thread thread;
}

private class Worker implements Runnable {
public boolean active = true;

public boolean done() {
return true;
}

public run() {
while (active) {
x = 1+1;
}
}

public void instakill() {
active = false;
}
}

public void mainLoop() {
int maxThreads = 50;

List<RunningInstanceEntry> instances =
new ArrayList<RunningInstanceEntry>();

while (true) {
for (R request : requests) {
if (threads.size < maxThreads) {
RunningInstanceEntry instance =
new RunningInstanceEntry();

instance.name = "unique name";
instance.worker = new Worker();
instance.thread = new Thread(instance.worker);
instance.thread.start();

instances.add(instance);
}
}

Iterator<RunningInstanceEntry> iterator =
instances.iterator();
while (iterator.hasNext()) {
RunningInstanceEntry instance = iterator.next();
if (instance.worker.done()) {
iterator.remove();
}
}
}
}
}

注意:此代码中还有很多其他改进机会,我个人认为它具有良好编码实践的示例。尽管如此,我还是不想过多偏离原始代码,因为我的目标是专门强调仅结构类和 iterator.remove() 的使用。方法。

关于java - 如何以正确的方式动态处理开始和结束线程和信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41969639/

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