在线程中使用同步
以下内容可以理解为什么?
我已经浏览了这篇帖子,但仍然无法组装它。
code1:
synchronized(this){
// some code
}
code2:
Object lock = new Object();
synchronized(lock){
// some code
}
有任何教程或一些链接来解释同步,就像他们向孩子解释一样?
What could be the understanding of the following?
I have gone through this post at SO but still at a loss to assemble it.
code1:
synchronized(this){
// some code
}
code2:
Object lock = new Object();
synchronized(lock){
// some code
}
Any tutorial, or some links to explain synchronized like they explain it to a child?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
基本上,Java 中的每个对象都有一个关联的“锁”。
当线程到达对synchronized(something)的调用时,它必须在继续之前获取某物的锁。如果你想一次只允许一个线程修改一个对象的状态,最明显的事情就是同步该对象的锁。如果允许并行调用不同的方法,则需要不同的锁。
如果您编写synchronized(this),或者只是synchronized,则线程必须获取与当前对象(调用其方法)关联的锁。
请注意,从 Java 5.0 开始,并发包提供了正确的 锁可以用来代替同步。
Basically there is a "lock" associated with every object in Java.
When a thread reaches a call to synchronized(something), it has to acquire the lock of something before continuing. If you want to allow only one thread at a time to modify the state of an object, the most obvious thing is to synchronize on the lock of that object. If different methods are allowed to be called in parallel, you need different locks for that.
If you write synchronized(this), or simply synchronized, the thread must acquire the lock associated with the current object (of which method is called).
Note that since Java 5.0 there concurrent package provides proper locks which can be used instead of synchronization.
在已经给出的优秀答案中没有提到的一件事是 code1 和 code2 之间的区别。在 code1 中,同步是在其中找到代码的对象的实例上进行的,而在 code2 中,同步是在对象内的特定锁定对象上进行的。
如果封闭类中只有两个同步块,则两者之间没有功能差异,但请考虑这一点:
如果两个线程尝试使用 CodeOneClass 的同一实例,则只能使用其中一个同时在两个受保护的代码块中中。
但是使用第二个习惯用法,您可以灵活地表示一个线程位于第一个受保护块中是安全的,而另一个线程位于另一个受保护块中是安全的。请注意,如果锁相同(都在同一个锁对象上同步),则行为将与第一个相同。
还有其他差异。一些作者开始指出 synchronized(this) 的问题 - 我会向您指出另一篇关于 SO 的文章:
我强烈建议阅读它,它链接的
三个帖子到。
One thing not mentioned in the otherwise excellent answers already given is that difference between code1 and code2. In code1, the synchronization is on the instance of the object in which the code is found, and in code2, it's on the specific lock object within the object.
If there's only the two synchronized blocks in the enclosing class, there's no functional difference between the two, but consider this:
If two threads are trying to use the same instance of CodeOneClass, only one of them can be in either of the two protected code blocks at the same time.
But with the second idiom, you have the flexibility to say that it's safe for one thread to be in the first protected block, and another to be in the other. Note that if the locks were the same (both synchronizing on the same lock object), the behavior would be as the first.
There are other differences. Some writers are beginning to point out issues with synchronized(this) - I would point you to another post here on SO:
Avoid synchronized(this) in Java?
I highly recommend reading it, and the three posts it links to.
将代码放在
synchronized
块中本质上意味着,“一旦此代码开始运行,需要使用此对象的其他代码就无法同时运行。”因此,如果线程 #2 正在执行
code2
块中的代码,那么当涉及到synchronized(lock)
代码时,它必须有效地环顾所有其他线程以确保此时没有其他人正在使用lock
对象运行“同步”代码。线程 #1 肯定同时运行一些代码,但它可能是完全不相关的代码。如果是这样,线程#2 就可以安全地开始运行“some code
”内容。同时,如果线程 #1 到达
synchronized(this)
块,它也必须暂停并查看是否有其他线程正在使用this
。如果this
与lock
是同一个对象,我们就会遇到问题。我们被告知只有一个线程可以同时使用该对象(在同步块中)。然而线程 #2 已经在使用它了。线程#1 只需要等待...等待...等待...直到线程#2 最终完成。然后我们就可以继续了。最终结果是一次只能运行一个
同步
块(当然是针对特定对象)。Putting code within a
synchronized
block essentially means, "Once this code starts running, other code that needs to use this object cannot run at the same time."So, if Thread #2 is executing code in your
code2
block, when it comes to thesynchronized(lock)
code it has to effectively look around at all the other threads to make sure nobody else is running "synchronized" code with thelock
object at the moment. Thread #1 is certainly running some code at the same time, but it might be completely unrelated code. If so, it's safe for Thread #2 to start running your "some code
" stuff.Meanwhile, if Thread #1 gets to the
synchronized(this)
block, it too has to pause and see if any other threads are usingthis
. Ifthis
is the same object aslock
, we have a problem. We were told that only one thread can possibly use that object (in a synchronized block) at the same time. Yet Thread #2 is already using it. Thread #1 will just have to wait... and wait... and wait... until eventually Thread #2 finishes. Then we can proceed.The end result is that only one
synchronized
block can run at a time (with a particular object, of course).假设您有一个
Account
对象,它有一个方法:现在假设您有一个余额为 100 欧元的帐户,并且您有两次尝试借记 70 欧元。如果两次借记同时发生,您可以得到如下的竞争条件:
我们可以通过同步
Account
对象的锁来防止这种可怕的情况:这可以确保对帐户余额和借方的测试可以'不会被帐户余额的另一次测试中断。
Sun Java 教程 是获取以下信息的好地方:并发和锁定。
Suppose you have an
Account
object which has a method:Now suppose you have an account with a balance of 100 euros, and you get two attempts to debit it by 70 euros. If the two debits occur at the same time, you can get a race condition like this:
We can prevent this dire state of affairs by synchronizing on the
Account
object's lock:This makes sure that the test on the account balance and the debit can't be interrupted by another test on the account balance.
The Sun Java tutorial is a good place to start for information on concurrency and locking.