线程未正确同步

问题描述:

我正在尝试创建一个类,用于计算5种不同形状的总面积和周长,但给定形状的每个面积和周长都是由单独的线程计算的。到目前为止,我无法让线程正确同步,因此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(); 
     } 
    } 
} 

Shape接口:

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; 
    } 
} 
+0

在您发布的代码中没有任何同步...... – Necreaux 2015-03-02 20:23:27

+1

它对我来说不是很清楚你想要什么?这些线程是做什么的?你为什么要同步?你想按什么顺序运行它们? – Cheiron 2015-03-02 20:24:16

+0

@Necreaux再次检查 – m0skit0 2015-03-02 20:38:49

我忘了还有一种方法,使主线程等待,直到某个线程没有活得更久。通过这样做,我能够使每个线程计算一个形状区域和边界,而不受其他线程的干扰。作为@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(); 
       } 
      } 
     } 
    } 

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