【问题标题】:Java - 4 Threads manipulate within two synchronized methods the same object dataJava - 4线程在两个同步方法中操作相同的对象数据
【发布时间】:2014-03-06 11:13:25
【问题描述】:

首先我是新来的,所以我希望我在提问时能做对所有事情。

问题:

我有一个类Store,其属性为int size;

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

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

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

如果我用size=2;for example 和 4 个其他对象(4 个线程)初始化 Store 对象 交替尝试leave()enter()Store object 我会得到一个无限循环。 我想如果我写同步方法,离开方法也可以被一个线程调用,尽管另一个线程会挂在无限循环中。

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

【问题讨论】:

  • 锁在对象上,而不是方法上。两个线程可以为不同的对象输入相同的方法。

标签: java multithreading concurrency synchronized


【解决方案1】:

首先我在这里很新,所以我希望我能把所有事情都做好 在提问期间。

你的问题问得很好,所以你至少是对的:)

4 个其他对象(4 个线程)交替尝试 leave() 或 enter()Store 对象我会得到一个无限循环

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

解决方案

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

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

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

【讨论】:

  • 哇,难以置信的快。谢谢! “...没有其他线程可以进入同一个对象的同步区域”意思是它不受同一个同步方法的限制?
  • 正确!受限于实例。
  • 好的,完美!谢谢!
  • 是的,这就是synchronized 关键字的全部意义所在。如果您想在功能级别执行此操作,则需要mutex
【解决方案2】:

与其他解决方案一样,您也可以考虑以下解决方案。在两件事上更好 1. 而不是同步方法减少锁定范围 2. 非常清晰的方法感谢使用等待通知解决方案

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();
        }
    }
}

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多