Java - 4 Threads在两个同步方法中操纵相同的对象数据

时间:2014-03-06 11:13:26

标签: java multithreading concurrency synchronized

首先,我在这里很新,所以我希望在提问过程中我能做好所有事情。

问题:

我的课程Store的属性为int size;

在这个类中有两种操作size属性的方法。

`public synchronized void leave(){
   this.size++;
}`

`public synchronized void enter(){
   while(this.size==0){ }
   this.size--;
}`

如果我使用size=2;和其他4个对象(4个线程)初始化存储对象 交替尝试leave()enter() Store object我将获得无限循环。 我想如果我编写同步方法,也可以通过线程调用leave方法,尽管其他线程会在无限循环中挂起。

我希望我的问题是可以理解的。 非常感谢你的帮助。

2 个答案:

答案 0 :(得分:2)

  

首先,我在这里很新,所以我希望我能做好一切   在质疑期间。

你的问题很好,所以你至少得到了正确的答案:)

  

其他4个对象(4个线程)交替尝试离开()或   输入()Store对象我将获得无限循环

当一个线程进入同步块时,您声明在线程离开初始同步块之前,没有其他线程可以进入同一对象的同步区域。你有一个线程调用enter并旋转直到大小为0.为此,大小需要增加,这是不可能的,因为另一个线程无法调用leave(而另一个线程正在旋转永远)。

<强>解决方案

在监视器上放置线程while(<some condition>){ },而不是忙于旋转(wait)。这将放弃锁定,以便另一个线程可以进入。在leave之后,通知任何等待的线程。

public synchronized void leave(){
   this.size++;
   this.notify();
}

public synchronized void enter(){
   while(this.size==0){ 
       this.wait();
   }
   this.size--;
}

答案 1 :(得分:0)

与其他解决方案相同,您也可以考虑以下解决方案。两件事情更好 1.而不是同步方法减少锁定范围 2.使用wait-notify解决方案感谢非常明确的方法

class ConditionExample {
    final Lock lock = new ReentrantLock();
    final Condition resourceAvailable = lock.newCondition();

    private int size = 2;

    public void leave() throws InterruptedException {
        lock.lock();
        try {
            size++;
            //signal other waiting threads
            resourceAvailable.signal();
        } finally {
            lock.unlock();
        }
    }

    public void enter() throws InterruptedException {
        lock.lock();
        try {
            //Check condition
            while (size == 0)
                resourceAvailable.await();
            size--;
        } finally {
            lock.unlock();
        }
    }
}

希望这有帮助。