class Thread wait(); notify(); notifyAll();

0

Witam!

Mam problem z metodami, wait() i notifyAll() klasy Thread. Tak mi się przynajmniej wydaje. Mianowicie notifyAll() zdaje sie budzic tylko jeden watek, na ktorym jest akurat wykonywana (Thread.currentThread().notifyAll(); ), zamiast wszystkich.

import java.util.Arrays;

public class Nbody extends Thread{

    public static final int n = 5; // number of bodies
    public static final double G = 6.674E-1;
    public static int workers = 2; //number of workers;
    public static double [][] p = new double[n][2];    //coordinates
    public static double [][] v = new double[n][2];    //velocity vectors
    public static double [][][] f = new double[workers][n][2];    //forces vectors
    public static double []   m = new double[n];       //mass
    public static int steps = 20; 
    public static int DT =1;   
    private int id;
    private static int counter;
    private static Nbody[] threads = new Nbody[workers];

    public void calculateForces(){
        double distance = 0;
        double magnitude = 0;
        int w = this.getNumber();
        System.out.println("Wystartował proces: "+w);
        double direction_x, direction_y = 0;
        for(int i=w;i<n;i+=workers){     //dla wszystkich ciał przypisanych do tego procesu 
                for(int k=i+1;k<n;k++){  //liczy uwzglegniajac symetrie                 
                        distance = Math.sqrt((p[i][0]-p[k][0])*(p[i][0]-p[k][0])+(p[i][1]-p[k][1])*(p[i][1]-p[k][1]));
                        magnitude=G*m[i]*m[k]/(distance*distance);
                        direction_x = p[k][0]-p[i][0];
                        direction_y = p[k][1]-p[i][1];

                        f[w][i][0]= f[w][i][0] + magnitude*direction_x/distance;
                        f[w][k][0]= f[w][k][0] - magnitude*direction_x/distance;
                        f[w][i][1]= f[w][i][1] + magnitude*direction_y/distance;  
                        f[w][k][1]= f[w][k][1] + magnitude*direction_y/distance; 

                }
            }
        counter++;
        System.out.println(w+" skończył. Licznik jest teraz: "+counter);
    }

    public static void main(String[] args) {
        for(int i=0;i<n;i++){   //initial values
            m[i]=1000; counter = 0;
            for(int j=0;j<2;j++){
                p[i][j]=i*100+1;
                v[i][j]=j;
                for(int a=0;a<workers;a++){
                    f[a][i][j]=0;   
                }       
            }   
        } 
            System.out.println("Velocities: ");
            print(v);
            System.out.println("Coordinates: ");
            print(p); 

            for (int i=0; i<threads.length; i++){ //uruchamiamy tyle procesów ile jest robotników
                threads[i] = new Nbody();
                threads[i].setNumber(i);
                threads[i].start();
    }
    }

    public void moveBodies(){
        double deltav_x,deltav_y;
        double deltap_x,deltap_y;
        double force_x =0;
        double force_y =0;
        int w = this.getNumber();
        System.out.println("Wystartowalo moveBodies: "+w);
        for(int i=w;i<n;i+=workers){
            for(int k=0;k<workers;k++){
                force_x+= f[k][i][0]; f[k][i][0]=0;
                force_y+= f[k][i][1]; f[k][i][1]=0;
            }
            deltav_x=(force_x*DT)/m[i];
            deltav_y=(force_y*DT)/m[i];
            deltap_x=(v[i][0]+deltav_x/2)*DT;
            deltap_y=(v[i][1]+deltav_y/2)*DT;
            v[i][0]=v[i][0]+deltav_x; 
            v[i][1]=v[i][1]+deltav_y; 
            p[i][0]=p[i][0]+deltap_x; 
            p[i][1]=p[i][1]+deltap_y; 
            force_x=0;
            force_y=0; 
        }
        counter++;
        System.out.println("Licznik jest teraz: "+counter);
        }

    private static void print(double[][] c){
        for (int i=0; i< c.length; i++)
            System.out.println(Arrays.toString(c[i]));
    }
    private int getNumber(){
        return id;
    }

    private void setNumber(int id){
        this.id=id;
    }

    public void run(){
        for (int l=0;l<steps;l++){
            calculateForces();
            barrier();
            moveBodies();
            barrier();
            System.out.println("Velocities: ");
            print(v);
            System.out.println("Coordinates: ");
            print(p);
        }

    }

    private synchronized void barrier(){
        if (counter >= workers){
            Thread.currentThread().notifyAll();
            //for (int i=0; i<threads.length; i++){ //opcja z informowaniem wszystkich procesow, tez nie dziala :/
            //  threads[i].notify();
           //}
            counter = 0;
                System.out.println("Zerowanie licznika: "+counter);
        } else {
            try{
                Thread.currentThread().wait();  
            }catch (InterruptedException e){

            }
        }

    }

}

Wynik działania:

Velocities: 
[0.0, 1.0]
[0.0, 1.0]
[0.0, 1.0]
[0.0, 1.0]
[0.0, 1.0]
Coordinates: 
[1.0, 1.0]
[101.0, 101.0]
[201.0, 201.0]
[301.0, 301.0]
[401.0, 401.0]
Wystartował proces: 0
0 skończył. Licznik jest teraz: 1
Wystartował proces: 1
1 skończył. Licznik jest teraz: 2
Zerowanie licznika: 0
Wystartowalo moveBodies: 1
Licznik jest teraz: 1
0

Nie czytalem kodu tylko wstep i na start powiem jedno: Twoje zalozenia sa zle, dlaczego uwazasz ze masz temetody wywolywac na Thread? Te metody sa dostepne dla kazdego obiektu w Javie.
Twoj problem wynika z kompletnego niezrozumienia prymitywow synchronizacji w Javie. Poczytaj o monitorach.

0

Dzięki, poczytanie pomogło :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0