当线程调用等待它释放锁定与竞争条件

问题描述 投票:0回答:3

根据来自synchronized methodlink的基本定义

“当一个线程正在为一个对象执行一个synchronized方法时,所有其他线程都会为同一个对象块调用同步方法(暂停执行),直到第一个线程完成该对象为止。”

我读到有关wait()的信息,它在sleeps之前释放锁定。如果wait释放lock然后其他thread可以进入synchronized method并且它有意义,因为它可能导致race condition,这里有一个混乱?

这是我的示例代码,允许onetwo线程进入synchronized块。

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Ashish Pancholi
 */
public class Test {

    public Test() {
        Sharing sharing = new Sharing();
        Worker worker_ = new Worker(sharing);
        Thread thread_ = new Thread(worker_, "one");
        Worker worker = new Worker(sharing);
        Thread thread = new Thread(worker, "two");
        thread_.start();
        thread.start();
    }

    public static void main(String[] argu) {
        Test test = new Test();
    }

    public class Worker implements Runnable {

        private Sharing sharing;

        public Worker(Sharing sharing) {
            this.sharing = sharing;
        }

        @Override
        public void run() {
            sharing.check();
        }
    }

    public class Sharing {

        public void check() {
            synchronized (this) {
                System.out.println("Thread IN " + Thread.currentThread().getName());
                try {
                    wait(5000);
                } catch (InterruptedException ex) {
                }
                System.out.println("Thread OUT " + Thread.currentThread().getName());
            }
        }
    }
}

输出 -

Thread IN one
Thread IN two
Thread OUT one
Thread OUT two
java multithreading
3个回答
1
投票

有可能存在竞争条件。在处理多个线程时,竞争条件自然会发生。通过仔细管理线程来阻止它们是你的工作,而wait方法是一个重要的工具,你可以用来帮助它。

通常情况下,你不会简单地用wait调用固定的5秒钟。在实际应用程序中,您可能正在等待某些特定条件成立,因此您的等待看起来更像是:

try {
    while(!condition) {
       wait();
    }
    doSomething();
} catch(InterruptedException e) {
    doSomethingElseWhenWeAreAskedNotToWait();
}

你是否有竞争条件取决于condition何时成为真实,还有谁可能在等待这种情况,以及每个人在发生时所做的事情。 wait放弃锁定的原因是让condition有机会在我们等待时变为真实。


2
投票

是的,这是有道理的。

wait()方法的API说:

导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法,或者已经过了指定的时间量。

因此,如果wait方法不会释放监视器对象上的锁,则没有其他线程可以获取它,因此没有其他线程可以在该监视器对象上调用notifynotifyAll

wait(5000)表示当前线程在继续之前将等待最多5000毫秒的通知,或者在5000毫秒之后继续。如果你想保持锁定并暂停5000毫秒,那么你必须使用Thread.sleep(5000)


0
投票

您正在使用带有两个不同锁的synchronized,因此两个线程之间不会发生同步。

Test而不是Sharing的实例上同步,行为将完全不同。

© www.soinside.com 2019 - 2024. All rights reserved.