2013-11-07 4 views
2

Допустит, я объявил класс как это:Блокировка в многопоточных приложениях C#

public class PersistableObject<TObject> where TObject : class, new() 
{ 
    private readonly object objectLocker = new object(); 
    private TObject persistableObject; 

    public TObject Object 
    { 
     get 
     { 
      lock (this.objectLocker) 
      { 
       return this.persistableObject; 
      } 
     } 

     set 
     { 
      lock (this.objectLocker) 
      { 
       this.persistableObject = value; 
      } 
     } 
    } 

    public bool Persist() 
    { 
     lock (this.objectLocker) 
     { 
      // Do Persist Object in file 
     } 
    } 

    public bool Retrieve() 
    { 
     lock (this.objectLocker) 
     { 
      // Do Retrieve Object from file 
     } 
    } 
} 

Этого класс отвечает за хранение переменного любого типа, сохраняется в файл и извлечь его из файла.

Как вы можете видеть, я использовал тот же замок (объект), чтобы заблокировать 4 операции:

  1. Получение реального объекта
  2. Установка фактического объекта
  3. сохранение объекта в файл
  4. Извлечение объекта из файла

Это правильный подход от параллелизм Точка зрения? Я полностью в безопасной зоне, учитывая, что этот класс используется разными потоками?

UPDATE:

Самое главное для меня здесь, только один поток должен иметь доступ к объекту в любой момент времени (независимо от того, что хочет получить, установить, восстановить или сохраняются его). Учитывая это, правильно ли он подходит? будут ли какие-либо тупики или другие неприятные вещи?

+0

Это зависит от того, как вы планируете использовать его, и о том, что вызывающие приложения * ожидают * этого. Когда один поток идет и устанавливает значение, а затем сохраняет его прямо после этого, нормально ли для другого потока установить другое значение между этими двумя вызовами метода? – Servy

+0

Скорее всего, вы планируете выполнять атомарные операции 'persist' и' retrieve', что не удается сделать полностью. –

+0

@Servy Нет, это не нормально, но практически никто не будет устанавливать объект напрямую.Темы используют объект (который является списком) для добавления или удаления объектов, и я в порядке с ним, потому что любые изменения должны быть сохранены. – Arashv

ответ

4

Thread-safety - это свойство всей системы, а не одного класса или метода. Отдельные операции над экземпляром этого класса будут выполняться исключительно, но, возможно, вам требуется, чтобы несколько операций были атомарными. У класса нет возможности сделать это.

Так это потокобезопасно или нет? Только вы можете сказать, потому что только вы знаете, как этот класс используется. Если операции над этим классом действительно независимы, то это безопасно.

Если все, что вы сделали, чтобы обеспечить безопасный поток для простого блокирования каждого члена любого класса, то нарезка будет простой задачей. Резьба сложна, поскольку она затрагивает все в поперечном разрезе.

+0

Нет. Я не ожидаю создания класса «Thread-Safe», просто помещая замок вокруг каждого его члена. – Arashv

+0

Позвольте мне выразить это по-другому. То, что я пытаюсь сделать, это убедиться, что, когда один поток обращается к члену «Объект», другой не может сохранять или извлекать объект. Теперь, этот код способен это сделать? Возможны ли ситуации взаимоблокировки? – Arashv

+0

Еще одна вещь, которую я могу добавить, - я не пытаюсь сделать атомические операции persist или retrieve, я хочу убедиться, что никто не изменится, не сохранится или не восстановит «объект», в то время как другой поток меняется, сохраняется или извлечение «объекта». Это скорее проблема параллелизма, чем просто защита потоков. Извините, что не упоминал об этом в вопросе – Arashv

0

Определите «находясь в безопасной зоне».

Представьте себе кусок кода, выполняющегося на несколько потоков, используя свой класс

  1. читать объект из файла
  2. изменить этот объект
  3. запись, что объект обратно в файл

Ни один из блокировок, которые вы здесь делаете, поможет сделать этот сценарий потокобезопасным.

Смежные вопросы