2011-04-03 24 views
2

我有多個文件和類。簡單地說,人們將計算一個粒子的位置,而另一個粒子移動粒子。我遇到的問題是在第一堂課完成計算之前,粒子正在移動。我試着讓兩種方法同步,但似乎沒有什麼不同,是因爲它們在不同的類中?什麼是最好的方法來做到這一點?如何在不同的類和文件中創建同步的方法?

編輯:我沒有使用線程,它似乎並行運行多個方法。

編輯2:這裏是我的代碼

MovingParticle.java 

public int x, y; 

public void shootParticle(){ 
//move particle and change x, y values 
//this method is called by a timer 
} 

public void drawParticle(){ 
//draws the particle 
} 

第二個文件的概要

AllOtherParticles.java 

public void checkIfTheyCollide(){ 
for(run through arrayList){ 
    //check if it collides with each point in array 
} 

public void drawCluster(){ 
//draws the cluster 
} 
+5

同步(TheParticle){...} – Erik 2011-04-03 22:59:54

+1

埃裏克,這應該是一個答案,所以我可以給予好評它:-) – meriton 2011-04-03 23:01:54

+0

有一個bug在你的代碼中,發佈代碼。 – ThomasRS 2011-04-03 23:17:57

回答

1

我試着讓兩種方法同步,但似乎並沒有改變,是因爲它們在不同的類中嗎?

是的,將同步修飾符添加到方法會同步調用該方法的對象。也就是說,

public synchronized void foo() { 
    // code 
} 

相當於

public void foo() { 
    synchronized (this) { 
     // code 
    } 
} 

由於方法駐留在不同的班級,this指的是不同的對象,因此不使用這兩種方法相同的鎖。

合理的方式來解決您的眼前的問題是做:

class Particle { 
    synchronized void setLocation(Location loc) { 
     // code 
    } 

    synchronized Location getLocation() { 
     return location; 
    } 
} 

編輯:當然,它假定多個線程參與。如果只有一個線程,​​不起作用,因此不會有幫助。

+0

調用getLocation()的方法是否保持足夠長的鎖以完成位置上的所有計算? – yousefcisco 2011-04-03 23:10:54

+0

有沒有一種方法來模擬沒有多線程的同步? – yousefcisco 2011-04-03 23:25:56

1

爲什麼要使用線程所有,而不是一個簡單的循環,採用了許多我不明白還在它的身體中的類。

但也許循環障礙會幫助你使用你的線程問題,我完全不明白。

使用循環屏障可以讓您在多個線程中從1到100進行計數,確保每個線程的速度不會比其他線程快1個以上。

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/CyclicBarrier.html

+0

對不起,我不清楚。我沒有使用多線程。看來我的程序在同一時間運行多種方法。 – yousefcisco 2011-04-03 23:06:53

+0

如果你不使用多線程,你的程序不會同時運行兩種方法。只需使用eclipe的調試器來解決你的問題,並請投票給我,因爲我只需要10+ 250 =) – 2011-04-03 23:09:35

1

同步的對象,你正在修改中的兩個線程。

synchronized (TheParticle) { 
    // Move it 
} 


synchronized (TheParticle) { 
    // Calculate on it 
} 
+0

該對象正在從一個方法中移動。雖然計算是在一個不同類的方法中完成的。 – yousefcisco 2011-04-03 23:08:45

+0

@yousefrisco:你可以使用'synchronized(this){...}' – Erik 2011-04-03 23:09:56

0

假設方法不是在同一個類的方法,如果你只是把他們定義爲​​他們不會在同一對象上同步。因此你沒有實現互斥。

如果你想兩個不同的類對同一個對象上同步,你需要做的是這樣的:

public class Particle { 
    public synchronized void foo() { 
     // ... in critical region 
    } 
} 

public class Mover { 
    public void bar() { 
     ... 
     synchronize (someParticle) { 
      // ... in critical region 
     } 
     ... 
    } 
} 

注意,這兩種方法需要在同一Particle實例同步。​​語句允許您在指定的實例上進行同步,而不是在this上進行同步。

0

我想我們可以在類上使用同步來實現兩個不同資源之間的同步。片段同步(X.class)使用類實例作爲監視器。看看下面的代碼和結果。糾正我,如果我錯了。

public class SyncTest1 { 
    public static void main(String[] args) { 
     System.out.println("Starting"); 
     SyncTest1 syncTest1 = new SyncTest1(); 
     Resource r1 = syncTest1.new Resource(); 
     Resource1 r2 = syncTest1.new Resource1(); 

    Runnable runnable = new Runnable() { 
     @Override 
     public void run() { 
      r1.printThread("T1"); 
     } 
    }; 

    Runnable runnable2 = new Runnable() { 
     @Override 
     public void run() { 
      r2.printThread("T2"); 
     } 
    }; 

    new Thread(runnable).start(); 
    new Thread(runnable2).start(); 

    System.out.println("Done"); 
} 

private class Resource { 

    public void printThread(String threadName) { 
     synchronized (String.class) { 
      try { 
       System.out.println(threadName + " Sleeping for 5 Sec"); 
       Thread.sleep(5000); 
       System.out.println(threadName + " Waked up after 5 sec"); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

private class Resource1 { 
    public void printThread(String threadName) { 
     synchronized (String.class) { 
      try { 
       System.out.println(threadName + " Sleeping for 5 Sec"); 
       Thread.sleep(5000); 
       System.out.println(threadName + " Waked up after 5 sec"); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

}

結果:

Starting 
Done 
T1 Sleeping for 5 Sec 
T1 Waked up after 5 sec 
T2 Sleeping for 5 Sec 
T2 Waked up after 5 sec