我有这个计算素数的程序。当按下停止时程序停止计算素数但是当我按GO时我需要程序继续其计算,但我无法找到如何再次启动我的线程。我尝试创建它的新实例但没有发生任何事情。这是我的代码:
public class PrimeApp1 extends JFrame {
protected JTextArea output;
protected JButton go;
protected JButton stop;
protected long counter = 2;
protected boolean stopComputation = false;
public boolean run = true;
protected boolean isPrime(long number) {
long max = (long) Math.sqrt(number) + 1;
for (long i = 2; i < max; i++) {
if ((number % i) == 0) {
return (false);
}
}
return (true);
}
public class PrintPrimes extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
int primecount = 0;
while (run == true) {
if (isPrime(counter)) {
primecount++;
output.append(Long.toString(counter) + "\n");
stop.setEnabled(true);
}
counter++;
}
}
}
public PrimeApp1() {
super("Prime Numbers");
final PrintPrimes print = new PrintPrimes();
JPanel content = new JPanel();
BorderLayout contentLayout = new BorderLayout();
content.setLayout(contentLayout);
output = new JTextArea();
output.setEditable(false);
JScrollPane scroller = new JScrollPane(output);
content.add(scroller, BorderLayout.CENTER);
JPanel buttonPane = new JPanel();
FlowLayout buttonPaneLayout = new FlowLayout();
buttonPane.setLayout(buttonPaneLayout);
go = new JButton("Go");
stop = new JButton("Stop");
stop.setEnabled(false);
buttonPane.add(go);
buttonPane.add(stop);
content.add(buttonPane, BorderLayout.SOUTH);
go.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
print.start();
}
});
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
run = false;
}
});
setContentPane(content);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 600);
setVisible(true);
}
public static void main(String[] args) {
new PrimeApp1();
}
}
答案 0 :(得分:0)
我认为您的问题是您正在尝试启动已完成处理的线程。您只能启动一次线程,有关详细信息,请参阅here。
您可能希望在该ActionListener中创建一个新的Thread对象并启动它,而不是在go动作侦听器中启动该线程。
这样的事情:
go.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PrintPrimes print = new PrintPrimes();
print.start();
}
});
而不是在构造函数中创建最终的Thread对象。
答案 1 :(得分:0)
这取决于你想要达到的目标。如果你想“暂停”那么你应该按照@Junen的建议将线程的运行同步到按下按钮。
如果您想重新启动,可以执行以下操作:
public class PrintPrimes extends Thread {
@Override
public void run() {
run = true; //You started the thread, hence when you enter run() it is running.
int primecount = 0;
while (run) {
if (isPrime(counter)) {
primecount++;
output.append(Long.toString(counter) + "\n");
stop.setEnabled(true);
}
counter++;
}
}
}
使print
成为一个类对象并更改它:
go.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
print = new Thread(PrimeApp1.this);
print.start();
}
});
答案 2 :(得分:0)
如果您想暂停线程,请尝试以下操作。请注意run
变量为volatile
,因为主线程在技术上修改了它。
我还注意到在您的代码示例中,您正在从PrintPrimes线程修改UI。从单独创建的线程更新用户界面通常是不好的做法。
How to update java GUI from Thread?就此问题提供了一些解释。
How to Pause and Resume a Thread in Java from another Thread提供了有关停止和恢复线程的一些其他信息。在run
方法中,我使用了类似的实现。
public class PrimeApp1 extends JFrame {
protected JTextArea output;
protected JButton go;
protected JButton stop;
protected boolean stopComputation = false;
protected boolean isPrime(long number) {
long max = (long) Math.sqrt(number) + 1;
for (long i = 2; i < max; i++) {
if ((number % i) == 0) {
return (false);
}
}
return (true);
}
public class PrintPrimes extends Thread {
private int current = 2;
private volatile boolean run = false;
public PrintPrimes() {
}
public void run() {
while (true) {
if (run == false)
continue; // thread paused
if (isPrime(current)) {
output.append(Long.toString(current) + "\n");
}
current++;
}
}
public void stopCount() {
run = false;
}
public void startCount() {
if (!run) {
if (current == 2)
start(); // start initial thread
run = true;
}
}
}
public PrimeApp1() {
super("Prime Numbers");
final PrintPrimes print = new PrintPrimes();
JPanel content = new JPanel();
BorderLayout contentLayout = new BorderLayout();
content.setLayout(contentLayout);
output = new JTextArea();
output.setEditable(false);
JScrollPane scroller = new JScrollPane(output);
content.add(scroller, BorderLayout.CENTER);
JPanel buttonPane = new JPanel();
FlowLayout buttonPaneLayout = new FlowLayout();
buttonPane.setLayout(buttonPaneLayout);
go = new JButton("Go");
stop = new JButton("Stop");
stop.setEnabled(false);
buttonPane.add(go);
buttonPane.add(stop);
content.add(buttonPane, BorderLayout.SOUTH);
go.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
go.setEnabled(false);
stop.setEnabled(true);
print.startCount();
}
});
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
stop.setEnabled(false);
go.setEnabled(true);
print.stopCount();
}
});
setContentPane(content);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 600);
setVisible(true);
}
public static void main(String[] args) {
new PrimeApp1();
}
}