Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-4线程在两个同步方法中操作相同的对象数据_Java_Multithreading_Concurrency_Synchronized - Fatal编程技术网

Java-4线程在两个同步方法中操作相同的对象数据

Java-4线程在两个同步方法中操作相同的对象数据,java,multithreading,concurrency,synchronized,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个线程) 或者尝试

首先,我是新来的,所以我希望在提问时把所有事情都做好

问题是:

我有一个类
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()
存储对象
I将得到一个无休止的循环。
我认为如果我编写同步方法,leave方法也可以被一个线程调用,尽管另一个线程将挂起在无限循环中

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

首先,我是新来的,所以我希望我能把所有事情做好 在审讯期间

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

4个其他对象(4个线程)交替尝试离开()或 enter()存储对象我将得到一个无止境的循环

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

解决方案

不要忙于旋转(
while(){}
),而是让线程在监视器上等待。这将放弃锁定,以便另一个线程可以进入。在
离开
ing后,通知所有等待的线程

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

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

在与其他溶液相同的注释中,也可以考虑折叠溶液。它有两个优点 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();
        }
    }
}

希望这能有所帮助。

哇,速度真快。非常感谢。“…没有其他线程可以进入同一对象的同步区域”表示它不受同一同步方法的限制?正确!它仅限于实例。好的,太好了!非常感谢。是的,这就是
synchronized
关键字的全部要点。如果您想在函数级别执行此操作,则需要一个
互斥锁
。锁在对象上,而不是方法上。两个线程可以为不同的对象输入相同的方法。