我有一个程序可以估算每百万次试验中PI的价值。但是,我希望在点击暂停时暂停程序,并在我点击运行时使用wait()
和notify()
恢复。
我必须使用多个线程以及Boolean
作为暂停和运行位置的信号,但我不知道如何。我很困惑。
有什么想法吗?
package com.company;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Ex03 extends JFrame implements Runnable, ActionListener {
int n = 0;
int c = 0;
double Pi;
int change = 1000000;
boolean runing = true;
JLabel actualpi = new JLabel("The Actual value of PI " + Math.PI);
JLabel estimation = new JLabel("Current Estimate: ");
JLabel tri = new JLabel("Number Of Trials: " + n);
JButton run = new JButton("Run");
JButton pause = new JButton("Pause");
public Ex03() {
super("Ex 03");
setLayout(new GridLayout(4, 1));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
setVisible(true);
add(actualpi);
add(estimation);
add(tri);
add(run);
run.addActionListener(this);
pause.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
Thread thread = new Thread(this);
if (e.getSource() == run) {
thread.start();
remove(run);
add(pause);
} else if (e.getSource() == pause) {
remove(pause);
add(run);
try {
thread.wait();
} catch (InterruptedException e1) {
}
}
}
public void run() {
n++;
while (runing) {
double x = Math.random();
double y = Math.random();
if (((x * x) + (y * y)) <= 1)
c++;
n++;
Pi = (4.0 * (double) c / n);
if (n == change) {
estimation.setText("Current Estimate: " + Pi);
tri.setText("Number Of Trials: " + n);
change = change + 1000000;
}
try {
Thread.sleep(0);
} catch (InterruptedException e) {
}
}
}
public static void main(String[] args) {
new Ex03();
}
}
答案 0 :(得分:0)
以下是使用Semaphore在控制台应用程序中执行此操作的示例:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
public class Main {
public static void main(String[] args) throws Exception {
PiThread piThread = new PiThread();
piThread.start();
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
String cmd;
while ((cmd = bufferRead.readLine()) != null) {
System.out.println("write p to pause, r to resume, s to stop");
switch (cmd) {
case "p":
piThread.pauseComputation();
break;
case "r":
piThread.resumeComputation();
break;
case "s":
piThread.stopComputation();
piThread.join();
return;
}
}
}
public static class PiThread extends Thread {
private volatile boolean stop = false;
private volatile int total = 0;
private volatile int insideCircle = 0;
private Semaphore semaphore = new Semaphore(1, true);
@Override
public void run() {
while (!stop) {
for (int i = 0; i < 1000; i++) {
double x = Math.random();
double y = Math.random();
if (((x * x) + (y * y)) <= 1)
insideCircle++;
total++;
}
// using semaphores is slow
try {
// not to garbage stdout
Thread.sleep(100);
semaphore.acquire();
semaphore.release();
}
catch (InterruptedException e) {
// exit
return;
}
System.out.println("pi: " + getPiApproximation());
System.out.flush();
}
}
public void pauseComputation() {
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void resumeComputation() {
semaphore.release();
}
public void stopComputation() {
stop = true;
}
public double getPiApproximation() {
return 4*(double)insideCircle / (double)total;
}
}
}
这可能不是在GUI中处理此问题的最佳方法,但会为您提供良好的开端。主要思想是使用Semaphore来阻止工作线程。为此,必须始终在resumeComputation之前调用pauseComputation,否则会出现死锁。在调用stopComputation之后,您无法恢复计算或暂停计算。