gpt4 book ai didi

Java线程不会被中断

转载 作者:行者123 更新时间:2023-11-30 02:36:35 26 4
gpt4 key购买 nike

我正在使用线程开发一个 Java 程序,并且不断遇到一些问题,我希望有人可以帮助我解决这个问题。

这是一个学校项目,我们必须制作一些科赫分形。

第一类是经理。这是创建线程以使用 EdgeGenerator 生成科赫分形边缘的位置。

import java.util.logging.Level;
import java.util.logging.Logger;
import uckochfractalfx.UCKochFractalFX;

public class KochManager {
private final UCKochFractalFX application;
private final IEdgeCollection edges;

private int level;
private int count;

public KochManager(UCKochFractalFX application) {
this.application = application;
this.edges = new EdgeArrayList();
}

public synchronized void changeLevel(int nxt){
this.level = nxt;
this.count = 0;
this.edges.clear();

EdgeGenerator left, right, bottom;
left = new EdgeGenerator(this, EdgeLocation.LEFT);
right = new EdgeGenerator(this, EdgeLocation.RIGHT);
bottom = new EdgeGenerator(this, EdgeLocation.BOTTOM);

Thread tLeft, tRight, tBottom;
tLeft = new Thread(left);
tRight = new Thread(right);
tBottom = new Thread(bottom);

tLeft.start();
tRight.start();
tBottom.start();

try {
tLeft.join(500);
tRight.join(500);
tBottom.join(500);
} catch (InterruptedException ex) {
Logger.getLogger(KochManager.class.getName()).log(Level.SEVERE, null, ex);
}


application.requestDrawEdges();
}

public void addEdge(Edge edge){
this.edges.add(edge);
}

public synchronized void increaseCount(){
count ++;
}

public int getLevel() {
return level;
}
}

第二个类是 EdgeGenerator,它实现了 Runnable 和 Observer。

可观察的是 KochFractal 类(此处不包括)。update 方法在 KochFractal 的generate__Edge() 方法上调用。这一切都工作得很好,并且在不使用线程和使用线程的情况下进行了测试。

import java.util.Observable;
import java.util.Observer;

public class EdgeGenerator implements Runnable, Observer {
private final KochManager kochManager;
private final EdgeLocation edgeLocation;
private final KochFractal koch;

public EdgeGenerator(KochManager kochManager, EdgeLocation edgeLocation) {
this.kochManager = kochManager;
this.edgeLocation = edgeLocation;
this.koch = new KochFractal();
this.koch.addObserver(this);
}


@Override
public void run() {
koch.setLevel(kochManager.getLevel());
switch (this.edgeLocation) {
case LEFT:
this.koch.generateLeftEdge();
break;
case RIGHT:
this.koch.generateRightEdge();
break;
case BOTTOM:
this.koch.generateBottomEdge();
break;
}
Thread.currentThread().interrupt();
}

@Override
public void update(Observable o, Object o1) {
this.kochManager.addEdge((Edge)o1);
this.kochManager.increaseCount();
}
}

这里的最后一个类是使用 ArrayList 的集合类。在添加和删除时我使用了同步关键字。据我了解,这使得实例方法一次只能由一个线程访问,并使其他线程处于搁置状态。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class EdgeArrayList implements IEdgeCollection{
private final List<Edge> edges;

public EdgeArrayList() {
this.edges = new ArrayList<>();
}

@Override
public synchronized void add(Edge e) {
edges.add(e);
}

@Override
public synchronized void remove(Edge e) {
edges.remove(e);
}

@Override
public void clear() {
edges.clear();
}

@Override
public List<Edge> getAll() {
return Collections.unmodifiableList(edges);
}
}

那么这是怎么回事呢?

  • 当我运行这里实现的程序时,GUI 中只显示了所有分形元素中的一小部分。然而,一旦需要计算大量边,GUI 中显示的边就会越来越少。使用调试器,我可以看到所有边缘都已计算完毕,但在计算所有边缘之前调用了 application.requestDrawEdges();
  • 当我在 join() 方法中没有延迟地运行程序时,它只是继续运行而不显示 gui。

据我所知Thread.currentThread().interrupt();应该停止当前线程并调用join()方法,但这并没有发生。

我希望有人能给我指明正确的方向。

最佳答案

你对join的理解是错误的。

您的主线程将简单地等待 500 毫秒让每个地下元素加入...但如果没有发生,代码执行将继续。换句话说:大约 1.5 秒后绘图将开始。

您可以让每个子线程主动宣布“我完成了”,而不是使用低级原始连接。而你的主线程只是等待所有子线程执行此操作。

除此之外:线程对象非常“昂贵”。你真的不应该在每次迭代后扔掉它们。相反:考虑使用 ExecutorService 来代替。您最初创建一项服务,然后将新任务推送到该服务中。与 Futures 一起应该可以提供更优雅的解决方案。正如 Hovercraft 建议的那样,您还可以允许更频繁地更新用户界面。

关于Java线程不会被中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42879379/

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