【问题标题】:Threads not being properly synchronized线程未正确同步
【发布时间】:2015-03-02 20:18:46
【问题描述】:

我正在尝试创建一个类来计算 5 种不同形状的总面积和周长,但给定形状的每个面积和周长都是由单独的线程计算的。到目前为止,我无法让线程正确同步,因此正确计算了 totalArea 和 totalPerimeter。有什么建议可以让线程正常工作吗?如果我不使用螺纹计算每个形状,下面代码的 totalArea 和 totalPerimeter 应该等于 610.829 的面积和 187.115 的周长。如果我这样做,这些值就会变得完全随机。

package PartB;

import PartA.Step2.*;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;



public class Picture implements Runnable{
    public List<Shape> picture;
    public Shape selectedShape;
    public ListIterator<Shape> e;
    double totalArea;
    double totalPerimeter;
    double a;
    double b;
    double c;
    double length;
    double width;
    double height;
    double radius;


    public Picture(double a, double b, double c, double length, double width, double height, double radius){
        this.a = a;
        this.b = b;
        this.c = c;
        this.length = length;
        this.width = width;
        this.radius = radius;
        this.height = height;
        Shape[] shapes = {new Circle(radius), new Square(length),
                new Rectangle(length, width), new Parallelogram(length, width, height),
                new Triangle(a, b, c)};
        picture = new CopyOnWriteArrayList<>(Arrays.asList(shapes));

    }

    public double getTotalArea(){return totalArea;}

    public double getTotalPerimeter(){return totalPerimeter;}


    @Override
    public void run() {

        synchronized (this) {
        totalArea += selectedShape.getArea();
        totalPerimeter += selectedShape.getPerimeter();
        System.out.println(totalArea);
        System.out.println(totalPerimeter);
    }

    }

    public static void main(String[] args){
        Picture pictures = new Picture(5, 6, 7, 8, 9, 10, 11);
        for(pictures.e = pictures.picture.listIterator(); pictures.e.hasNext();){
            pictures.selectedShape = pictures.e.next();
            new Thread(pictures).start();
        }
    }
}

形状界面:

package PartA.Step2;

public interface Shape {
    double getPerimeter();
    double getArea();
}

形状的子类之一:

package PartA.Step2;

public class Circle implements Shape, Cloneable {
    double radius;


    public Circle(double radius){
        this.radius = radius;
    }
    @Override
    public double getArea() {
        CalculateShape calc = (radius)->Math.PI * Math.pow(radius[0], 2);
        return calc.process(radius);

    }

    @Override
    public double getPerimeter() {
        CalculateShape calc = (radius)->2 * Math.PI * radius[0];
        return calc.process(radius);

    }



    @Override
    public String toString() {
        return "Area: " + getArea() +
                "\nPerimeter : " + getPerimeter();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Circle){
            if(((Circle) obj).radius == radius)
                return true;
        }
        return false;
    }
}

【问题讨论】:

  • 您发布的代码中没有任何同步...
  • 我不太清楚你想要什么?这些线程有什么作用?为什么要同步?你想以什么顺序运行它们?
  • @Necreaux 再次检查
  • 因为你没有在同一个对象上同步?
  • @Cheiron 我希望每个线程计算图片中形状的总面积和总周长。由于有 5 种不同的形状,因此制作了 5 条线,每条线都计算给定形状的总面积和总周长,并将这些值添加到图片的总面积和周长中。

标签: java multithreading concurrency synchronized


【解决方案1】:

我忘记了有一种方法可以让主线程等到一个线程不再活动。通过这样做,我能够让每个线程计算形状面积和周长,而不受其他线程的干扰。正如@cheiron 所说,同步部分没有意义:

 public static void main(String[] args){
        Picture pictures = new Picture(5, 6, 7, 8, 9, 10, 11);
        for(pictures.e = pictures.picture.listIterator(); pictures.e.hasNext();){
            pictures.selectedShape = pictures.e.next();
            Thread thread = new Thread(pictures);
            thread.start();
            while(thread.isAlive()){
                try {
                    thread.join();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }

我现在得到了整张图片的正确总面积和总周长。

【讨论】:

    猜你喜欢
    • 2016-10-31
    • 1970-01-01
    • 2023-03-17
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    相关资源
    最近更新 更多