简体   繁体   English

Java同步方法

[英]Java synchronized method

Consider this code:考虑这个代码:

public synchronized void onSignalsTimeout(List<SignalSpec> specs) {
    if (specs != null && specs.size() > 0) {
        for (SignalSpec spec : specs) {
            ParsedCANSignal timeoutedSignal = new ParsedCANSignal();
            SignalsProvider.getInstance().setSignal(spec.name, spec.parent.parent.channel, timeoutedSignal);
        }
    }
}

I've got simple question: When Thread 1 calls onSignalsTimeout method, can Thread 2 access objects that are accessed in that method?我有一个简单的问题:当线程 1 调用 onSignalsTimeout 方法时,线程 2 可以访问在该方法中访问的对象吗?

Can't find anywhere if 'synchronized' locks only access to this method or access to all objects used in this method.如果“同步”锁定仅访问此方法或访问此方法中使用的所有对象,则找不到任何地方。

First of all, forget about synchronized methods . 首先,忘记同步方法 A so-called synchronized method... 一种所谓的同步方法......

synchronized AnyType foobar(...) {
    doSomething();
}

Is nothing but a shortcut way of writing this: 只不过是写这篇文章的捷径:

AnyType foobar(...) {
    synchronized(this) {
        doSomething();
    }
}

There is nothing special about the method in either case. 在任何一种情况下,该方法都没有什么特别之处。 What is special is the synchronized block , and what a synchronized block does is very simple. 有意义的是同步 ,同步块的作用非常简单。 When the JVM executes this: 当JVM执行此操作时:

synchronized(foo) {
    doSomething();
}

It first evaluates the expression foo . 它首先评估表达式foo The result must be an object reference. 结果必须是对象引用。 Then it locks the object, performs the body of the synchronized block, and then it unlocks the object. 然后它锁定对象,执行synchronized块的主体,然后解锁对象。

But what does locked mean? 锁定是什么意思? It may mean less than you think. 这可能意味着比你想象的要少。 It does not prevent other threads from using the object. 不会阻止其他线程使用的对象。 It doesn't prevent them from accessing the object's fields or, from updating its fields. 它不会阻止它们访问对象的字段,也不会阻止它们更新其字段。 The only thing that locking an object prevents is, it prevents other threads from locking the same object at the same time. 锁定对象唯一阻止的是,它可以防止其他线程同时锁定同一个对象。

If thread A tries to enter synchronized(foo) {...} while thread B already has foo locked (either in the same synchronized block, or in a different one), then thread A will be forced to wait until thread B releases the lock. 如果线程A试图进入synchronized(foo) {...}而线程B已经具有FOO锁定(无论是在相同的synchronized块中,或在不同的一个),然后线程A将被迫等待,直到线程B释放锁。


You use synchronized blocks to protect data . 您使用synchronized块来保护数据

Suppose your program has some collection of objects that can be in different states . 假设您的程序有一些可以处于不同状态的对象集合。 Suppose that some states make sense, but there are other states that don't make sense— invalid states. 假设一些国家是有意义的,但也有其他规定,不要让正义- 无效状态。

Suppose that it is not possible for a thread to change the data from one valid state to another valid state without temporarily creating an invalid state. 假设线程无法在不临时创建无效状态的情况下将数据从一个有效状态更改为另一个有效状态。

If you put the code that changes the state in a synchronized(foo) block, and you put every block of code that can see the state into a synchronized block that locks the same object , foo , then you will prevent other threads from seeing the temporary invalid state. 如果你把改变状态的代码放在synchronized(foo)块中,并且你将每个可以看到状态的代码块放入一个锁定同一个对象 foo的同步块中,那么你将阻止其他线程看到暂时无效的状态。

Yes, other threads can access the objects used in the method; 是的,其他线程可以访问方法中使用的对象; the synchronized keyword guarantees that no more than one thread at the time can execute the code of the method. synchronized关键字保证当时只有一个线程可以执行该方法的代码。

From https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html : 来自https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

  • First, it is not possible for two invocations of synchronized methods on the same object to interleave. 首先,对同一对象的两个同步方法的调用不可能进行交错。 When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object. 当一个线程正在为对象执行同步方法时,所有其他线程调用同一对象的同步方法(暂停执行)直到第一个线程完成对象。
  • Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. 其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立先发生关系。 This guarantees that changes to the state of the object are visible to all threads. 这可以保证对所有线程都可以看到对象状态的更改。 Note that constructors cannot be synchronized — using the synchronized keyword with a constructor is a syntax error. 请注意,构造函数无法同步 - 将synchronized关键字与构造函数一起使用是一种语法错误。 Synchronizing constructors doesn't make sense, because only the thread that creates an object should have access to it while it is being constructed. 同步构造函数没有意义,因为只有创建对象的线程在构造时才能访问它。

在此上下文中, synchronized同时锁定此方法以及类中标记为synchronized任何其他方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM