Конструктор экземпляра устанавливает статического участника, действительно ли это ориентировано на многопотоковое исполнение?

По состоянию на 16 апреля 2015 года с выпуском R 3.2.0 появилась новая функция под названием dir.exists(). Чтобы использовать эту функцию и создать каталог, если он не существует, вы можете использовать:

ifelse(!dir.exists(file.path(mainDir, subDir)), dir.create(file.path(mainDir, subDir)), FALSE)

Это вернет FALSE, если каталог уже существует или является недоступным, и TRUE, если он не существовало, но было успешно создано.

Обратите внимание, что просто проверить, существует ли каталог, вы можете использовать

dir.exists(file.path(mainDir, subDir))
5
задан buræquete 14 December 2017 в 03:09
поделиться

7 ответов

@ajmastrean

Я не говорю, что необходимо использовать сам шаблон "одиночка", но принять его метод инкапсуляции процесса инстанцирования.

т.е.

  • Сделайте конструктора частным.
  • Создайте статический метод экземпляра, который возвращает тип.
  • В статическом методе экземпляра используйте ключевое слово блокировки перед инстанцированием.
  • Инстанцируйте нового экземпляра типа.
  • Увеличьте количество.
  • Разблокируйте и возвратите новый экземпляр.

Править

Одна проблема, которая произошла со мной, если, как Вы знали бы, когда количество понизилось?;)

ОТРЕДАКТИРУЙТЕ СНОВА

Думая об этом, Вы могли добавить код к деструктору, который называет другой статический метод постепенно уменьшить счетчик :D

3
ответ дан 18 December 2019 в 06:36
поделиться

Если Вы только увеличиваете число, существует специальный класс (Взаимно блокируемый) для просто этого...

http://msdn.microsoft.com/en-us/library/system.threading.interlocked.increment.aspx

Взаимно блокируемый. Инкрементный метод

Увеличивает указанную переменную и хранит результат, как атомарная операция.

System.Threading.Interlocked.Increment(myField);

Больше информации о поточной обработке лучших практик...

http://msdn.microsoft.com/en-us/library/1c9txz50.aspx

12
ответ дан 18 December 2019 в 06:36
поделиться

Я предполагаю, что это для шаблона "одиночка" или чего-то как он. То, что Вы хотите сделать, не является блокировкой Ваш объект, но заблокируйте счетчик, в то время как Ваш изменяют его.

private static int counter = 0;
private static object counterLock = new Object();

lock(counterLock) {
    counter++;
    myCounter = counter;
}

Поскольку Ваш текущий код является видом избыточных. Особенно находясь в конструкторе, где существует только один поток, который может вызвать конструктора, в отличие от этого, с методами, откуда он мог быть совместно использован через потоки и получен доступ любого потока, который совместно используется.

От мало я могу сказать от Вас код, Вы пытаетесь дать объекту текущее количество во время него создаваемый. Таким образом с вышеупомянутым кодом счетчик будет заблокирован, в то время как счетчик обновляется и устанавливается локально. Таким образом, все другие конструкторы должны будут ожидать в противоречии с быть выпущенными.

4
ответ дан 18 December 2019 в 06:36
поделиться

Можно использовать другой статический объект для соединения его.

private static Object lockObj = new Object();

и заблокируйте этот объект в конструкторе.

lock(lockObj){}

Однако я не уверен, существуют ли ситуации, которые должны быть обработаны из-за компиляторной оптимизации в .NET как в случае Java

3
ответ дан 18 December 2019 в 06:36
поделиться

Самый эффективный способ сделать это должно было бы использовать Взаимно блокируемую инкрементную операцию. Это увеличит счетчик и возвратится недавно установленное значение статического счетчика внезапно (атомарно)

class MyClass {

    static int _LastInstanceId = 0;
    private readonly int instanceId; 

    public MyClass() { 
        this.instanceId = Interlocked.Increment(ref _LastInstanceId);  
    }
}

В Вашем исходном примере блокировка (этот) оператор не будет иметь желаемого эффекта, потому что каждый отдельный экземпляр будет иметь другое "этой" ссылкой, и несколько экземпляров могли таким образом обновлять статического участника одновременно.

В некотором смысле конструкторы могут считаться ориентированными на многопотоковое исполнение, потому что ссылка на создаваемый объект не видима, пока конструктор не завершился, но это не приносит пользы для защиты статической переменной.

(У Mike Schall был взаимно блокируемый бит сначала),

2
ответ дан 18 December 2019 в 06:36
поделиться

Я думаю, изменяете ли Вы Шаблон "одиночка" для включения количества (очевидно, использующий ориентированный на многопотоковое исполнение метод), Вы будете в порядке :)

Править

Дерьмо я случайно удалил!

Я не уверен, ориентированы ли конструкторы экземпляра на многопотоковое исполнение, я не забываю читать об этом в книге шаблонов разработки, необходимо удостовериться, что блокировки существуют во время процесса инстанцирования, просто из-за этого..

0
ответ дан 18 December 2019 в 06:36
поделиться

@Rob

К вашему сведению Этот класс не может быть одиночным элементом, мне нужен доступ к различным экземплярам. Они должны просто поддержать количество. Какую часть шаблона "одиночка" Вы изменили бы для выполнения 'встречного' постепенного увеличения?

Или Вы предлагаете, чтобы я выставил статический метод для доступа блокирующего конструкции к коду, который увеличивает и читает счетчик с блокировкой.

public MyClass {

    private static Int32 counter = 0;
    public static MyClass GetAnInstance() {

        lock(MyClass) {
            counter++;
            return new MyClass();
        }
    }

    private Int32 myCount;
    private MyClass() {
        myCount = counter;
    }
}
0
ответ дан 18 December 2019 в 06:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: