Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中的类Java线程同步#_C#_Java_Multithreading_Thread Safety - Fatal编程技术网

C# C语言中的类Java线程同步#

C# C语言中的类Java线程同步#,c#,java,multithreading,thread-safety,C#,Java,Multithreading,Thread Safety,我是一名Java程序员,我知道一些关于Java线程的知识 在Java中,我可以使用synchronized关键字锁定方法: private int a; private int b; private int c; private synchronized void changeVars() { a = 4; b = 2; c = a+b; } 我在msdn中搜索,发现c#中有一些玩具可以玩线程。例如monitor.Enter、monitor.Exit、lock或高级互斥锁 但我需要

我是一名Java程序员,我知道一些关于Java线程的知识

在Java中,我可以使用synchronized关键字锁定方法:

private int a;
private int b;
private int c;
private synchronized void changeVars()
{
  a = 4;
  b = 2;
  c = a+b;
}
我在msdn中搜索,发现c#中有一些玩具可以玩线程。例如monitor.Enter、monitor.Exit、lock或高级互斥锁

但我需要的是同步一个方法。在c#中它的等价物是什么


提前谢谢。

像这样的事情可能会:

using System.Runtime.CompilerServices;

...

private int a;
private int b;
private int c;

[MethodImpl(MethodImplOptions.Synchronized)]
private void changeVars()
{
  a = 4;
  b = 2;
  c = a+b;
}

首选的解决方案是将方法体包装在
lock
语句中

internal class Foo
{
   private Object lockObject = new Object();

   private void ChangeVars()
   {
      lock (this.lockObject)
      {
         // Manipulate the state.
      }
   }
}
您也可以使用声明性同步,但这有一个明显的缺点,您必须从中派生,并且所有使用该属性修饰的方法共享同一个锁对象,从而限制了锁的粒度

internal class Foo : ContextBoundObject
{
   [Synchronization]
   private void ChangeVars()
   {
      // Manipulate the state.
   }
}

在C#中没有直接的等价物,但您可以用它做同样的事情:

private readonly object changeVarsLockObject = new object();

private void changeVars()
{
  lock(changeVarsLockObject)
  {
    a = 4;
    b = 2;
    c = a+b;
  }
}

直接等效于使用锁(此):

或者使用R.Bemrose所描述的MethodImplAttribute,这相当于一件事:

[MethodImpl(MethodImplOptions.Synchronized)]
private void ChangeVars()
{
    a = 4;
    b = 2;
    c = a+b;
}
。。。但是,不建议使用公开可见的对象进行锁定,因为其他人可能会决定将其用作锁定对象,因此更好的翻译是:

private object monitor = new object();
private void ChangeVars()
{
    lock (monitor) {
        a = 4;
        b = 2;
        c = a+b;
    }
}

需要澄清的是,在Java中声明同步的方法需要调用方在调用该方法的对象(静态方法的
对象)上持有监视器

因此,说您可以“锁定一个方法”是误导性的,因为您没有完全锁定该方法(相同的方法仍然可以在不同的实例对象上调用),并且您锁定的方法比该方法多(没有其他需要目标对象监视器的代码位,包括其他同步方法或显式获取的代码可以同时运行)

同步很难,理想情况下,如果希望避免在测试过程中几乎从未出现的死锁和可见性问题,或者有助于调试,则需要了解更多有关同步的信息。对一种语言中的同步有可能不完全的理解,并试图将其带到另一种具有不同原语和可能不同的内存模型的语言中,这将导致灾难


所以,虽然这不是你一直在寻找的一条线性答案,但我要断言,如果没有整个生态系统的知识支持,任何一条线性答案都注定会失败。因此,您应该阅读一本关于C#中的同步的好书/教程,而不是试图一个关键字一个关键字地翻译您的Java体验。

不是用C#中的语言;我最好说在C#中没有等价的关键字,但是你可以编写代码来做同样的事情;我认为MethodImpl比lock(this)更好,因为它让编译器选择最好的方法。可能值得一提的是,MethodImplOption.Synchronized和lock(this)都不再建议作为编写线程安全方法的方法,因为它们会造成死锁。下面的博客有更多的细节:“因此,你应该读一本关于C#中同步的好书/教程,而不是试图一个关键字一个关键字地翻译你的Java体验。”等等,你是认真地暗示这在Java中不是一个问题吗?+1不知道关于同步的关键字。是否可以从对象外部获取等效锁?@FacticiusVir,您可以使用synchronized(instance)获取与Java在该实例上输入声明为synchronized的方法时相同的锁(或显式使用Monitor方法)。@Freed No,我得到的C#/.NET代码,因为我对.NET同步结构做了很多工作;这是我不熟悉的Java代码。这就是为什么我问这个问题;如果Java中没有与C#中的lock(instance)等价的方法,那么Java中的“synchronized”和C#中的“lock(this)”之间有着重要的区别。@FacticiusVir,synchronized关键字可以在Java中的块级别使用,就像C#中的lock关键字一样,并且方法上的synchronized确实使用对象实例,或类实例(如果用于静态方法)。这个答案中没有任何东西与此相矛盾,dtsazza只是指出被锁定的不是方法。
private object monitor = new object();
private void ChangeVars()
{
    lock (monitor) {
        a = 4;
        b = 2;
        c = a+b;
    }
}