Оба параметра int
и string
как параметры этого метода являются фактически неизменяемыми и не могут быть изменены внешним кодом.
Таким образом, нет необходимости заботиться о безопасности нитей с помощью метода Format или String.Concat в этом случае.
Но давайте предположим, что мы имеем некоторый класс MyObject, что изменчиво и может быть изменен из-за пределов:
public class MyClass
{
public Int32 value1 { get; set; }
public String value2 { get; set;}
}
public static string WriteResult2(MyObject obj)
{
return "Result: value=" + obj.value1 + " name=" + obj.value2 ;
}
В этом случае, можно ли с первого захода на посадку или второй возврате противоречивое значение (это как value1, так и value2 изменяются после того, как одно значение уже отправлено на вывод.)
Как @JonSkeet pointed, это не сам метод, который является небезопасным, но сам класс небезопасен для совместного использования между различными потоками ,
Чтобы справиться с этой ситуацией, вам придется либо создать специальный поточно-метод экземпляра:
public class MyClass
{
private Object lockObj = new Object();
public Int32 value1
{
get
{
lock (this.lockObj) { ... });
}
set
{
lock (this.lockObj) { ... });
}
}
public String value2
{
get
{
lock (this.lockObj) { ... });
}
set
{
lock (this.lockObj) { ... });
}
}
public string WriteResult2()
{
lock (this.lockObj)
{
return "Result: value=" + this.value1 + " name=" + this.value2 ;
}
}
}
Или использовать некоторые дополнительные блокировки над такими экземплярами в методах, которые используют его. Первый подход в классе, очевидно, менее подвержен ошибкам, но может снизить производительность и создать много кода котельной. В идеальном случае при параллельном программировании вам меньше нужно заботиться об общем изменчивом состоянии и его последовательности the better.
Я бы не сказал, что ваш последний случай делает * метод * thread-unsafe - он небезопасен для * экземпляров * (MyClass) для обмена экземплярами между несколькими потоками, что немного отличается от IMO. –
Ваша «поточно-безопасная» версия на самом деле не является потокобезопасной ... потому что любой другой поток может изменять значения «value1» и «value2», не приобретая вообще никакой блокировки. –
@JonSkeet спасибо. Забыл добавить замки. –