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