具有暂停/继续计算功能的多线程

时间:2018-12-13 22:55:16

标签: java multithreading continue resume suspend

我正在编写Java程序,该程序可以让我获得随机生成的二维点的几何中心。我希望通过自定义线程数来完成计算。我想随时暂停/继续计算。不幸的是,我的代码无法正常工作,似乎从未执行过run()。这是我得到的:

public void run() {
    while (!Thread.currentThread().isInterrupted()) {

        try {
            System.out.println("running... " + Thread.currentThread().getName());

            PointInterface p = pg.getPoint(); // getting random point(x,y)
            pointCount++;
            int[] pos = p.getPositions(); // getting (x,y)
            System.out.println(pos[0] + ", " + pos[1] + " k");
            sumxy[0] += pos[0];
            sumxy[1] += pos[1];
            geometricCenter[0] = (double) sumxy[0] / pointCount;
            geometricCenter[1] = (double) sumxy[1] / pointCount;

            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println("exception caught in run()");
            return;
        }
    }
}

设置线程数:

public void setNumberOfThreads(int threads) {

    threadsList.clear();

    for (int i = 0; i < threads; i++) {
        threadsList.add(new Thread());
    }
}

开始计算:

public void start() {

    try {
        for (Thread t : threadsList) {
            t.start();
        }
    } catch (Exception e) {
        System.out.println("start() exception caught");

    }
}

暂停计算:

public void suspendCalculations() {

    try {
            Thread.sleep(1200);
    } catch (InterruptedException e) {
        System.out.println("SuspendCalculations() exception caught");
    }
}

继续计算: 我不完全知道该怎么办。我应该这样创建新的线程集吗?

public void continueCalculations() {

    int x = threadsList.size();
    threadsList.clear();

    for (int i = 0; i < x; i++) {
        threadsList.add(new Thread());
        threadsList.get(i).start();
    }
}

我如何运行程序:

public static void main(String[] args) {

    ParallelCalculations pc = new ParallelCalculations(); // My main class object where run() and all the methods above are declared
    PointGenerator g = new PointGenerator(); // class that allows me to generate points
    PointInterface a = g.getPoint(); // getting random point

    pc.setNumberOfThreads(3);
    pc.setPointGenerator(g);
    pc.start();
    pc.suspendCalculations();
    System.out.println(pc.getGeometricCenter()[0] + ", " + pc.getGeometricCenter()[1]);

    pc.continueCalculations();
    pc.suspendCalculations();
    System.out.println(pc.getGeometricCenter()[0] + ", " + pc.getGeometricCenter()[1]);
}

如果需要: 点:

class Point {

    public static final int MAX_POSITION = 16;
    private int[] positions = new int[2];

    Point(int _x, int _y) {
        this.positions[0] = _x;
        this.positions[1] = _y;
    }

    public int[] getPositions() {
        return positions;
    }
}

点生成器:

class PointGenerator {

    private int x = (int) (Math.random() * (Point.MAX_POSITION + 1));
    private int y = (int) (Math.random() * (Point.MAX_POSITION + 1));

    public PointInterface getPoint() { //  Can be called by many Threads at the same time.

        return new Point(x, y);
    }
}

1 个答案:

答案 0 :(得分:0)

您的run()应该被执行并且应该做。

尽管此代码中产生随机行为的原因要大得多:所有线程同时向sumxygeometricCenterpointCount写入而没有任何同步锁,导致或多或少的随机行为。您至少需要实现某种同步,以防止同时写入。

如果您不了解,也许可以开始here(Oracle的Java synchonized教程)。

但是仅向所有内容添加同步可能会使其比单个线程慢,您将需要某种缓冲区来使每个线程独立工作,而不是在挂起时收集结果。

现在是一般问题:

A)您的suspendCalculations()不执行任何操作(精确到1200毫秒)。要中断计算,您将需要中断所有工作线程,因为它们会在中断时终止。致电threadsList.get(i).Interrupt()

B)如果您希望能够在挂起时更改线程数,这是一种方法。如果不必这样做,则创建一个常量

会更有效。
 public static final Object LOCK = new Object();

在该对象上创建所有线程LOCK.wait(),因此恢复它们只是对LOCK.notifyAll()的调用。

C)可以使用java.awt.Point来代替使用自己的Point实现。

D)仅在数组中返回点的坐标确实不利于代码的可读性,java.awt.Point具有getX()getY()函数。