[英]Synchronized statements — create objects to provide locks so update of c1 wouldn't interleave with update of c2
I'm new to Java and is trying to learn the concept of Synchronized statements. 我是Java的新手,正在尝试学习同步语句的概念。 I saw the paragraph and the code below from Java Tutorial Oracle.
我从Java教程Oracle中看到了本段和下面的代码。 My question is
我的问题是
1) Under what kind of circumstances does update of c1 interleaves with update of c2. 1)在什么情况下c1的更新与c2的更新交织。
2) How does the object 'lock1' and 'lock2' prevent update of c1 interleaves with the update of c2. 2)对象'lock1'和'lock2'如何防止c1更新与c2更新交错。
I'm really struggling to understand the concept. 我真的很难理解这个概念。
Synchronized statements are also useful for improving concurrency with fine-grained synchronization.
同步语句对于通过细粒度同步提高并发性也很有用。 Suppose, for example, class MsLunch has two instance fields, c1 and c2, that are never used together.
例如,假设类MsLunch有两个实例字段c1和c2,它们从未一起使用。 All updates of these fields must be synchronized, but there's no reason to prevent an update of c1 from being interleaved with an update of c2 — and doing so reduces concurrency by creating unnecessary blocking.
这些字段的所有更新都必须同步,但是没有理由阻止c1更新与c2更新交织—这样做会通过创建不必要的阻塞来减少并发性。 Instead of using synchronized methods or otherwise using the lock associated with this, we create two objects solely to provide locks.
代替使用同步方法或以其他方式使用与此关联的锁,我们仅创建两个对象来提供锁。
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock2) {
c2++;
}
}
}
When you have a synchronized method : 当您有一个同步方法时:
public synchronized void inc1() {
c1++;
}
It is implicitly converted to : 它隐式转换为:
public void inc1() {
synchronized(this) {
c1++;
}
}
SO, if you make both inc1
and inc2
synchronized methods, then they both need to get hold of the current object ( this
) monitor and then increment . 因此,如果您同时使
inc1
和inc2
方法都同步 ,则它们都需要获取当前对象( this
)监视器,然后进行递增 。
But since c1++
and c2++
are independent, they should not be blocked because we are using a single lock. 但是由于
c1++
和c2++
是独立的,因此不应阻塞它们,因为我们使用的是单个锁。 What we must ensure is that multiple calls to inc1()
and inc2()
should be blocked in seperate sandboxed ways ie, an access to inc1()
by thread 1 should not block access to inc2()
by thread-2. 我们必须确保的是,多次调用
inc1()
和inc2()
应被阻止在沙盒独立的方式,即,向接入inc1()
由线程1不应该阻止访问inc2()
由线程2。 Having different locks will do this. 具有不同的锁将执行此操作。
The implication is that there might be other threads using the same MsLunch
object. 暗示是可能有其他线程使用同一
MsLunch
对象。 For example, you might start two threads like so: 例如,您可以像这样启动两个线程:
MsLunch ml = new MsLunch();
Thread thread1 = new Thread() {
public void run() { while (true) ml.inc1(); }
};
Thread thread2 = new Thread() {
public void run() { while (true) ml.inc2(); }
};
thread1.start();
thread2.start();
There are now two threads running in parallel, one that calls inc1()
in a loop and another that calls inc2()
in a loop. 现在有两个线程并行运行,一个调用
inc1()
在一个循环中,另一个调用inc2()
在一个循环中。
By having separate locks for these two methods the two threads won't slow each other down. 通过为这两种方法分别设置锁,两个线程不会彼此放慢速度。 If you had a shared lock then
inc1()
and inc2()
wouldn't be able to run at the same time. 如果您具有共享锁,那么
inc1()
和inc2()
将无法同时运行。 Any time you called one the other would block until the first call finished. 任何时候您互相呼叫都会阻塞,直到第一个呼叫结束。
Thread thread3 = new Thread() {
public void run() { while (true) ml.inc2(); }
};
Contrast this to what happens if you add a third thread that also calls inc2()
. 将此与如果添加第三个线程也调用
inc2()
会发生的情况进行对比。 Thread #1 is free to call inc1()
as fast as it likes. 线程#1可以随意调用
inc1()
。 Meanwhile, threads #2 and #3 both want to call inc2()
, so they will fight each other to do so. 同时,线程#2和#3都希望调用
inc2()
,因此它们将互相争斗。 If thread #2 is calling inc2()
then thread #3 will block until that call finishes. 如果线程2正在调用
inc2()
则线程3将阻塞直到该调用结束。 And vice versa, if thread #3 is in the middle of a call then thread #2 will have to wait. 反之亦然,如果线程#3在调用中间,则线程#2将不得不等待。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.