gpt4 book ai didi

java - 具有 ExecutionService 和共享对象的 SwingWorker

转载 作者:行者123 更新时间:2023-12-02 10:23:19 24 4
gpt4 key购买 nike

我花了好几个小时试图找出实验室练习的要求之一。

计划摘要

PrimeSeekerTask生成一个范围之间的素数。PrimeSeekerDisplay 是一个显示在 PrimeSeekerTask 中完成的工作的类。PrimeSeekerTask 应该在后台进行“繁重”计算。我需要为 PrimeSeekerTask 扩展 SwingWorker

在程序运行期间,应该有多个 PrimeSeekerTask 实例来执行一小部分计算。我需要使用 ExecutionService

此外,程序应在单击开始按钮时启动,并在单击取消按钮时中断。

当我将任务作为单个后台 SwingWorker 运行时,它工作正常(如本屏幕截图所示)enter image description here

但程序规范是我应该运行许多 SwingWorker 对象。

我的问题。

  1. 当我尝试使用 ExecutionService 时,程序挂起并消耗了几乎 100% 的 CPU,笔记本电脑开始崩溃。对于小数字,我得到错误的百分比值和找到的质数。我猜想有一些同步错误,但我认为 Atomic 修复了其中的一些错误?

  2. 我的取消按钮不会中断任务。

任何形式的帮助将不胜感激。

下面是我的真实尝试(我删除了导入以使代码更短)

public class PrimeSeekerDisplay extends JFrame
implements ActionListener, PropertyChangeListener {

private JLabel topLabel;
private JTextArea textArea;
private JProgressBar progressBar;
private JButton startButton;
private JButton cancelButton;
private JLabel primesFoundLabel;

private final long max;
private final long chunkSize;
PrimeSeekerTask task = null;
private final int THREAD_NUMBER = 9;
ExecutorService executorService = Executors
.newFixedThreadPool(THREAD_NUMBER);

/**
*
*/
private static final long serialVersionUID = 6602966318374691217L;

/**
*
*/
public PrimeSeekerDisplay(final long max, final long chunkSize) {
super("Prime Seeker");
this.max = max;
this.chunkSize = chunkSize;
initGui();

}

/*
* initGui() creates all the components and lays them on the display
*/
private final void initGui() {

// the top label
topLabel = new JLabel("Primes in [1.." + String.valueOf(max) + "]");
final JPanel topPanel = new JPanel();
topPanel.add(topLabel);
topPanel.setBorder(new EmptyBorder(5, 5, 5, 5));

// the text area
final JScrollPane textPane = createTextArea();

// the progress bar
progressBar = new JProgressBar(0, 100);
progressBar.setStringPainted(true);
progressBar.setBorder(BorderFactory.createLineBorder(Color.BLACK));

// the buttons and items in the status pane
startButton = createButton("Start");
// enable this at the beginning of program.
// This will be disabled when clicked
startButton.setEnabled(true);

cancelButton = createButton("Cancel");
// Disable cancel before program starts.
// Once program starts, this will be enabled
cancelButton.setEnabled(false);

// update this with number of primes found.
// only print something here when atleast a prime is found
primesFoundLabel = new JLabel();
primesFoundLabel.setEnabled(false);

final JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
statusPanel.setBorder(new EmptyBorder(10, 0, 0, 0));
statusPanel.add(startButton);
statusPanel.add(cancelButton);
statusPanel.add(primesFoundLabel);

// Jpanel to hold all components
final JPanel displayPanel = new JPanel();
displayPanel.setLayout(new BoxLayout(displayPanel, BoxLayout.Y_AXIS));

// add components to the display panel
displayPanel.add(topPanel);
displayPanel.add(textPane);
displayPanel.add(progressBar);
displayPanel.add(statusPanel);
displayPanel.setBorder(new EmptyBorder(10, 10, 10, 10));

// add the displayPanel to the frame
add(displayPanel);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
}

/**
* Create the text area embedded inside a ScrollPane
*
* @return a JScrollPane object
*/
private JScrollPane createTextArea() {
textArea = new JTextArea(8, 40);
textArea.setMargin(new Insets(5, 5, 5, 5));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
final JScrollPane scrollPane = new JScrollPane(textArea);
return scrollPane;
}

/**
* A method for creating a JButton
*
* @param text The text to display on the button This value in lower
* case is also the actionCommand
* @return A JButton with text, actionCommand, and action listener set
*/
private JButton createButton(final String text) {
final JButton button = new JButton(text);
button.setActionCommand(text.toLowerCase());
button.addActionListener(this);
return button;
}

/*
* (non-Javadoc)
*
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.
* ActionEvent)
*/
@Override
public void actionPerformed(ActionEvent e) {

if (e.getActionCommand().equalsIgnoreCase("start")) {
startButton.setEnabled(false);
cancelButton.setEnabled(true);
textArea.setText(null);
primesFoundLabel.setText("Nothing found yet");

// ####### Attempt to run many PrimeSeekerTasks fails ######
// ****** i need help here and how to cancel the process///
/*
int chunk = (int) (max / chunkSize);

System.out.println("chunk => " + chunk);
int remainder = (int) (max % chunkSize);

for (int index = 0; index < chunk; index++) {
final long lower = index * chunkSize;
final long upper = (index == chunk - 1
? (lower + remainder + chunkSize)
: (lower + chunkSize));
System.out.println("Index: " + index + " Lower: " + lower
+ " upper: " + upper);
PrimeSeekerTask primer = new PrimeSeekerTask(lower, upper);
primer.addPropertyChangeListener(this);
executorService.submit(primer);
}

*/
// =======
//Running this works very well but it is not according to
// program specs
// ===========

task = new PrimeSeekerTask(1, max);
task.addPropertyChangeListener(this);
task.execute();

}
if (e.getActionCommand().equalsIgnoreCase("cancel")) {
if (task != null) {
task.cancel(true);
}
startButton.setEnabled(true);
cancelButton.setEnabled(false);
//executorService.shutdownNow();
}

}

/**
* PrimeSeekerTask generatates prime numbers in a range and updates the
* progressBar, textArea and primesFoundLabel
*
*
* @author longb
*
*/
private class PrimeSeekerTask extends SwingWorker<String, String> {

private final long lowerRange;
private final long upperRange;
private final AtomicInteger progressMade = new AtomicInteger(0);
private final AtomicLong primesFound = new AtomicLong(0);

/**
* @param upperRange
* @param lowerRange
*/
public PrimeSeekerTask(final long lowerRange, final long upperRange) {
super();
this.lowerRange = lowerRange;
this.upperRange = upperRange;

}

/*
* (non-Javadoc)
*
* @see javax.swing.SwingWorker#doInBackground()
*/
@Override
protected String doInBackground() throws Exception {
while (!isCancelled()) {
for (long lower = lowerRange; lower < upperRange; lower++) {

if (isPrime(lower)) {
primesFound.getAndIncrement();
publish(String.valueOf(lower));
primesFoundLabel.setText(
"Primes found: " + primesFound.intValue());
}
progressMade.getAndIncrement();

int progress = (int) (100 * (progressMade.intValue() + 1)
/ upperRange);
setProgress(progress);
}

}
return "\n";
}

/*
* (non-Javadoc)
*
* @see javax.swing.SwingWorker#process(java.util.List)
*/
@Override
protected void process(List<String> chunks) {
for (String string : chunks) {
textArea.append(string + ", ");
}

}

/*
* (non-Javadoc)
*
* @see javax.swing.SwingWorker#done()
*/
@Override
protected void done() {
startButton.setEnabled(true);
cancelButton.setEnabled(false);
}
}

private boolean isPrime(final long number) {
final long limit = (long) Math.sqrt(number) + 1;

if (number < 2) {
return false;
}

for (long i = 2; i < limit; ++i) {
if ((number % i) == 0) {
return false;
}
}
return true;
}

/*
* (non-Javadoc)
*
* @see java.beans.PropertyChangeListener#propertyChange(java.beans.
* PropertyChangeEvent)
*/
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
int progress = (int) evt.getNewValue();
progressBar.setValue(progress);
}
}

}

//在 Run.java 中

public class Run {

/**
*
*/
public Run() {
// TODO Auto-generated constructor stub
}

/**
* @param args
*/
public static void main(String[] args) {

if (args.length == 3) {
for (int i = 0; i < args.length; i++) {
System.out.println("arg#" + i + " : " + args[i]);
}
try {
long max = Integer.valueOf(args[1]);
long chunksize = Integer.valueOf(args[2]);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
PrimeSeekerDisplay display = new PrimeSeekerDisplay(max,
chunksize);
display.setVisible(true);
}
});
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.err.println("\nUsage: lab8 maxValue chunkSize\n");
}
}

}

提前致谢。

最佳答案

此答案与发布的第二个问题相关:“我的取消按钮不会中断任务”。
您有一个 while 循环,当 isCancelled() 返回 false 时,该循环应该停止:

`while (! isCancelled())`

问题是,它后面跟着一个 for 循环。仅当 for 循环完成时才会评估停止条件。
要克服它,只需添加

if (isCancelled() ) { break;} 

for循环内。

第一个问题需要更多调查。
(注意one question per post policy)

关于java - 具有 ExecutionService 和共享对象的 SwingWorker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54164914/

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