gpt4 book ai didi

c# - 关于 Java 中的 synchronized 关键字(和 C# 的锁)的几个问题

转载 作者:行者123 更新时间:2023-11-30 19:32:55 24 4
gpt4 key购买 nike

  1. 以下类在 Java 中是否等价?如果不是,为什么?

    class Abc {
    private int c = 0;


    <pre><code>public synchronized void add(int a) {
    c += a;
    }


    public synchronized void subtract(int a) {
    c -= a;
    </code></pre>

    }
    }


    class Def {
    private int c = 0;
    private final Object lock = new Object();


    <pre><code>public void add(int a) {
    synchronized(lock) {
    c += a;
    }
    }


    public void subtract(int a) {
    synchronized(lock) {
    c -= a;
    }
    </code></pre>

    }
    }
  2. 此外,在 Def 中使用 this 作为同步参数而不是 lock 会出现什么问题?以下是问题所在吗?

    Def def = new Def()
    synchronized (def) {
    def.add(5); //originates deadlock? or is this allowed AS LONG
    //as all this happens in the same thread?
    }
  3. Java中的synchronized语句和C#的lock语句一样吗?如果不是,它们的区别是什么?如果是,为什么 C# 不像 Java 那样也允许锁定方法?

  4. 所以我猜 synchronized (this) 的问题可以用下面的例子来描述?

    class Xyz {
    private int c;


    <pre><code> public void add(int a) {
    synchronized(this) {
    c += a;
    }
    }


    public void subtract(int a) {
    synchronized(this) {
    c -= a;
    }
    }


    public void show666() {
    return 666;
    }
    </code></pre>

    }

    线程 1 调用 xyz.add(0),同时线程 2 尝试调用 xyz.show666()。 Thread2 必须等待 Thread1 完成 xyz.add(0) althtough 它不需要任何与锁直接相关的信息。是吗?

最佳答案

1 Are the following classes equivalent in Java? if no, why?

它们因同步的实例不同而不同,因此会受到这些实例之间差异的影响。

Class Abc 使用调用该方法的 Abc 实例。其他有权访问该实例的代码也可以通过在同步块(synchronized block)中显式使用该实例来使用它进行同步。

Def 类中的同步代码块明确命名了它们与之同步的实例。由于此实例是 Def 实例私有(private)的,因此 Def 外部的代码无法使用它进行同步(除非该实例以某种方式泄露)。

有些人可能会争辩说 Def 方法安全得多,封装你的锁很重要,原因与你应该使用私有(private)实例变量的原因相同。

最后,synchronized 关键字和使用 synchronized 语句是有区别的,例如synchronized 语句可以锁定任何对象,而不仅仅是执行代码的实例,synchronize 关键字稍微更有效等。

2a Also, what would be the problem of in Def, using this as synchronized parameter instead of lock?

没问题。在实例方法上使用 synchronized 关键字在语义上等同于将方法的代码包装在在 this 上同步的同步块(synchronized block)中(synchronized 关键字稍微更有效)。在静态方法上使用 synchronized 关键字与在类本身上使用 synchronized block 相同(例如 synchronized(FooBar.class) { ... })。

2b Is the following the problem?

不,Java 中的锁是可重入的,这只是意味着在保护实例上持有锁的线程可以进入和退出在同一实例上同步的任何其他代码块。

3a Are synchronized statements in Java just like C#'s lock statements? If no, what are their differences?

语义等价。

http://en.csharp-online.net/CSharp_FAQ:_What_is_the_difference_between_CSharp_lock_and_Java_synchronized#Synchronized_code_blocks

但请注意关于 Monitor.EnterMonitor.Exit 的回答

Are there any differences between Java's "synchronized" and C#'s "lock"?

3b If yes, why doesn't C# also allow to lock the methods, like Java allows?

确实如此 - 使用 [MethodImpl(MethodImplOptions.Synchronized)] 注释。

http://en.csharp-online.net/CSharp_FAQ:_What_is_the_difference_between_CSharp_lock_and_Java_synchronized#Synchronized_methods

4 Thread1 calls xyz.add(0) and at the same time Thread2 tries to call xyz.show666(). Thread2 has to wait for Thread1 to finish with xyz.add(0) althtough it doesn't need any info directly related with the lock. Is that it?

不,很多人认为“锁定”一个实例会影响整个实例。它只影响在该实例上同步的同步代码(同步方法和同步语句中的代码)。非同步代码不受影响(至少在它遇到同步语句或调用同步方法之前)。

非同步方法 show666() 不会导致线程阻塞。如果将 synchronized(this) 语句更改为 synchronized 方法,则不会发生任何变化 - show666 也不会阻塞(除非它也已同步)。

关于c# - 关于 Java 中的 synchronized 关键字(和 C# 的锁)的几个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4591914/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com