Java 同步方法
Java synchronized method
考虑这段代码:
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);
}
}
}
我有一个简单的问题:
Thread 1调用onSignalsTimeout方法时,Thread 2是否可以访问该方法中访问的对象?
如果 'synchronized' 仅锁定对该方法的访问或对该方法中使用的所有对象的访问,则找不到任何地方。
在此上下文中,synchronized
同时锁定此方法以及在您的 class.
中类似地标记为 synchronized
的任何其他方法
是的,其他线程可以访问该方法中使用的对象; synchronized 关键字保证同一时间不超过一个线程可以执行该方法的代码。
来自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.
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 AnyType foobar(...) {
doSomething();
}
不过是写这个的捷径:
AnyType foobar(...) {
synchronized(this) {
doSomething();
}
}
在任何一种情况下,方法都没有什么特别之处。比较特别的是synchronizedblock,一个synchronized块做的事情很简单。当 JVM 执行此操作时:
synchronized(foo) {
doSomething();
}
它首先计算表达式foo
。结果必须是对象引用。然后锁定对象,执行 synchronized
块的主体,然后解锁对象。
但是 locked 是什么意思?这可能意味着比你想象的要少。它不会 阻止其他线程使用该对象。它不会阻止他们访问对象的字段或更新其字段。锁定对象唯一可以防止的是,它可以防止其他线程同时锁定同一个对象。
如果线程 A 试图进入 synchronized(foo) {...}
而线程 B 已经锁定了 foo(在同一个 synchronized
块中,或者在不同的块中),那么线程 A 将被迫等待直到线程 B 释放锁。
您使用 synchronized
个块来保护 数据。
假设您的程序有一些可以处于不同状态 的对象集合。假设一些状态有意义,但还有其他状态没有意义——无效个状态。
假设如果不临时创建无效状态,线程不可能将数据从一个有效状态更改为另一个有效状态。
如果你把改变状态的代码放在一个synchronized(foo)
块中,然后你把每个个代码块放在see 状态进入同步块,锁定 同一个对象 ,foo
,然后你将防止其他线程看到临时无效状态。
考虑这段代码:
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);
}
}
}
我有一个简单的问题: Thread 1调用onSignalsTimeout方法时,Thread 2是否可以访问该方法中访问的对象?
如果 'synchronized' 仅锁定对该方法的访问或对该方法中使用的所有对象的访问,则找不到任何地方。
在此上下文中,synchronized
同时锁定此方法以及在您的 class.
synchronized
的任何其他方法
是的,其他线程可以访问该方法中使用的对象; synchronized 关键字保证同一时间不超过一个线程可以执行该方法的代码。
来自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. 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 AnyType foobar(...) {
doSomething();
}
不过是写这个的捷径:
AnyType foobar(...) {
synchronized(this) {
doSomething();
}
}
在任何一种情况下,方法都没有什么特别之处。比较特别的是synchronizedblock,一个synchronized块做的事情很简单。当 JVM 执行此操作时:
synchronized(foo) {
doSomething();
}
它首先计算表达式foo
。结果必须是对象引用。然后锁定对象,执行 synchronized
块的主体,然后解锁对象。
但是 locked 是什么意思?这可能意味着比你想象的要少。它不会 阻止其他线程使用该对象。它不会阻止他们访问对象的字段或更新其字段。锁定对象唯一可以防止的是,它可以防止其他线程同时锁定同一个对象。
如果线程 A 试图进入 synchronized(foo) {...}
而线程 B 已经锁定了 foo(在同一个 synchronized
块中,或者在不同的块中),那么线程 A 将被迫等待直到线程 B 释放锁。
您使用 synchronized
个块来保护 数据。
假设您的程序有一些可以处于不同状态 的对象集合。假设一些状态有意义,但还有其他状态没有意义——无效个状态。
假设如果不临时创建无效状态,线程不可能将数据从一个有效状态更改为另一个有效状态。
如果你把改变状态的代码放在一个synchronized(foo)
块中,然后你把每个个代码块放在see 状态进入同步块,锁定 同一个对象 ,foo
,然后你将防止其他线程看到临时无效状态。