2

I relative new with delphi XE2, I want to know about something, if I have like this code

TSomeClass=class
strict private
class var
   FCounter:integer;
public
   class procedure SomeProcedure();static
end;

implementation
class procedure SomeProcedure()
begin
  inc(FCounter);
end;

initialization
begin
   FCounter:=0;
end;

finalization
begin
  FCounter:=0;
end;

As my understanding, SomeProcedure() will static on memory, and single instance,

my question

  1. if TSomeClass accessed by many thread, TSomeClass thread-safe or not? or it will make overlapping between thread?
  2. if yes, do I need critical section for each thread? or another approach for that kind of method...
  3. if two different thread accessed this method, how about FCounter? FCounter will count sequential from last value or different thread with different value start from zero?
3
  • Calling with TSomeClass.SomeProcedure you can see it as a simple procedure which might or might not be threadsave, dependend on implementation. Using SomeClassInstance.SomeProcedure might crash if assignment of SomeClassInstance changed. Commented May 23, 2013 at 5:20
  • Yes, as bummi implies you will need to use critical sections or some other sync primitive to protect against data corruption if updating state in a multithreaded scenario. Commented May 23, 2013 at 5:37
  • Yes, if that method implementation accessed another data on another class, its not thread safe, I update my question to make clear my point, how about class static method that only access class var at same class? Commented May 23, 2013 at 6:49

2 Answers 2

7

There is no synchronization between different invocations of methods. If the methods, no matter what type of methods they are, access shared data, then synchronization may be needed.

It does not make any difference if they method is a class method or an instance method, static or dynamic, etc. All that matters is whether or not there are shared objects being accessed from multiple threads.

If two different thread accessed this method, how about FCounter? FCounter will count sequential from last value or different thread with different value start from zero?

In your code, FCounter is a class variable. There is a single instance of the variable, shared between all threads. A class variable is just a global variable, nothing more, nothing less.

Your code modifies that shared variable. As written the code has a data race. You can solve it with synchronization. For example by using InterlockedIncrement rather than inc.

class procedure SomeProcedure;
begin  
  InterlockedIncrement(FCounter); 
end;

For more complex objects you'd serialize with a critical section.

Sign up to request clarification or add additional context in comments.

2 Comments

I upadate my question to make clear my point, yes method access shared data, if that data is accessible to another method outside this method, but how about data that only accessible same class with that method?
Your question was already clear and the update does not change my message. You are misunderstanding sharing. What is important, as I said, is sharing between threads rather than sharing between classes. The unit of parallel execution is the thread and not the class.
5

Your class is not thread safe.

The easiest way to get the counter thread safe is to use TInterlocked.Increment(FCounter) instead of Inc(FCounter). All TInterlocked methods are executed as atomic operations, the same applies for the Windows API function InterlockedIncrement() which could be used here as well.

1 Comment

The solution with TInterlocked was first posted in my answer. It seems unfair to copy the solution from another answer and then get the acdepted answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.