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