我正在编写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);
}
}
答案 0 :(得分:0)
您的run()
应该被执行并且应该做。
尽管此代码中产生随机行为的原因要大得多:所有线程同时向sumxy
,geometricCenter
和pointCount
写入而没有任何同步锁,导致或多或少的随机行为。您至少需要实现某种同步,以防止同时写入。
如果您不了解,也许可以开始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()
函数。