我想暂停并恢复我的计划

时间:2016-04-23 14:35:01

标签: java wait notify

我有一个程序可以估算每百万次试验中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();
    }
}

1 个答案:

答案 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之后,您无法恢复计算或暂停计算。