简体   繁体   English

同步语句-创建对象以提供锁,因此c1的更新不会与c2的更新交织

[英]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 . 因此,如果您同时使inc1inc2方法都同步 ,则它们都需要获取当前对象( 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.

相关问题 不同对象上的同步语句可以交错吗? - Can synchronized statements on different objects interleave? 接口I中有methodX,类C1和C2使用方法X的确切代码,那么将逻辑放入方法X的位置在哪里? (JAVA) - There is methodX in Interface I, class C1 & C2 use the exact code of methodX, so where to put the Logic into methodX? (Java) 如何扁平化此列表 <C1> 其中C1使用Stream API包含单个元素的C2集合? - How to flatten this List<C1> where C1 contains a collection of C2 of a single element using Stream API? 可以使用isAssignableFrom检查Java中C1是C2的子类型吗? - can I use isAssignableFrom to check C1 is a subtype of C2 in Java? 在下面的程序中,c1和c2有什么区别,两个声明都相同吗? - What is the difference between c1 and c2 in the below program, are both declarations same? 在 Java Azure 函数中默认启用 JDK Hotspot C1 编译器并禁用 C2 - JDK Hotspot C1 compiler is enabled and C2 is disabled by default in Java Azure functions 分发我没有。 n中的项目数 箱,其中每个箱具有不同的容量级别c1,c2 - Distribute i no. of items in n no. of boxes, where each box has different capacity level c1, c2 如何使用 Bouncy Castle ElGamal 和 javax.crypto.Cipher 使加密(c1,c2)元组显式 - How to Make Encryption (c1, c2) Tuple Explicit using Bouncy Castle ElGamal and javax.crypto.Cipher C2中的CompilerThread - C2 CompilerThread in java 如何在Java中恢复对对象的引用。 在下面的代码中,我已将c1分配给c2。 如何将具有(50,30)值的对象还原到c2 - how to restore reference of your object in java. In code below i have assigned c1 to c2. How can restore the object having (50, 30) values back to c2
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM