我有多个文件和类。简单地说,一个人将计算一个粒子的位置,而另一个类移动粒子。我遇到的问题是在第一个类完成计算之前移动了粒子。我尝试将两种方法同步,但似乎没有区别,是因为它们在不同的类中?最好的方法是什么?
编辑:我根本不使用线程,似乎它正在并行运行多个方法。
编辑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
}
答案 0 :(得分:1)
我还没有得到你为什么使用线程,而不是一个简单的循环,在它的身体中使用了很多类。
但也许Cyclic Barrier可以帮助你使用你的线程问题,我完全不理解。
使用循环屏障可以让你,例如在多个线程中从1到100计数,确保一个线程比其他线程快一步。
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/CyclicBarrier.html
答案 1 :(得分:1)
在两个线程中同步您正在修改的对象。
synchronized (TheParticle) {
// Move it
}
synchronized (TheParticle) {
// Calculate on it
}
答案 2 :(得分:1)
我尝试将两种方法同步,但这似乎没有区别,是因为它们在不同的类中?
是的,将synchronized修饰符添加到方法会同步调用该方法的对象。也就是说,
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;
}
}
编辑:当然,这假定涉及多个线程。如果只有一个帖子,synchronized
没有效果,因此无效。
答案 3 :(得分:0)
假设这些方法不是同一个类的方法,如果只是将它们声明为synchronized
,它们就不会在同一个对象上同步。因此,您尚未实施互斥。
如果要在同一个对象上同步两个不同的类,则需要执行以下操作:
public class Particle {
public synchronized void foo() {
// ... in critical region
}
}
public class Mover {
public void bar() {
...
synchronize (someParticle) {
// ... in critical region
}
...
}
}
请注意,这两种方法需要在同一Particle
实例上同步。 synchronized
语句允许您在指定的实例上进行同步,而不是在this
上进行同步。
答案 4 :(得分: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