我有以下方法
public synchronized void run()
{
while (done.get()!=true) {
System.out.println(">>> Golfer #"+ myID + " trying to fill bucket with "+getBallsPerBucket()+" balls.");
golferBucket = sharedStash.getBucketBalls();
if(golferBucket.length == 0){
try {
sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(Golfer.class.getName()).log(Level.SEVERE, null, ex);
}
}
System.out.println("<<< Golfer #"+ myID + " filled bucket with "+getBallsPerBucket()+" balls, size = "+sharedStash.getSizeStash());
使用此同步方法:
public synchronized golfBall[] getBucketBalls() {
golfBall[] bucket = new golfBall[sizeBucket];
if (getSizeStash().intValue() >= sizeBucket) {
for (int i = 0; i < sizeBucket; i++) {
bucket[i] = stash.poll();
}
sizeStash.set(sizeStash.intValue() - sizeBucket);
System.out.println("minusing");
return bucket;
}
return new golfBall[0];
}
然而,当我经营两个不同的高尔夫球手时,线程,它允许两个线程同时访问getBucketBalls()方法。我不知道如何解决这个问题,因为我认为当一个线程获得锁定时,同步来自其他线程的方法锁定访问。另外我在另一篇文章中读到锁对实例有效,但我只有一个BallStash实例,这是getBucketBalls()方法所在的位置。
我得到的输出是:
======= River Club Driving Range Open ========
======= Golfers:5 balls: 20 bucketSize:5 ======
>>> Golfer #1 trying to fill bucket with 5 balls.
>>> Golfer #2 trying to fill bucket with 5 balls.
minusing
minusing
<<< Golfer #2 filled bucket with 5 balls, size = 10
<<< Golfer #1 filled bucket with 5 balls, size = 10
请帮忙。感谢。
答案 0 :(得分:0)
您现有的方法无法奏效。在评论中,您声明您的方法属于不同的类别。
如果两个方法在不同的类中,则在方法定义中使用synchronized关键字不会有帮助。在方法定义中使用时,synchronized类似于在类定义上进行同步。
此:
public class MyClass{
public synchronized void aMethod(){
// do stuff
}
}
等同于:
public class MyClass{
public void aMethod(){
synchronized(this){
// do stuff
}
}
}
这意味着你的run()方法和你的getBucketBalls()没有使用相同的对象来控制访问。如果他们没有在同一件事上同步,那么没有什么能阻止他们同时运行。
如果要同步两个不同类中的方法,则需要创建一个可以用作锁的Object,例如:
Object lockObj = new Object();
public void aMethod(){
synchronized(lockObj){
// do stuff
}
}
lockObj可以是任何对象,因此在您的情况下,您可以
public void run(){
synchronized(ballStash){
// do work
}
}
public void getBucketBalls(){
synchronized(ballStash){
// do work
}
}