简体   繁体   中英

Determinate when an object not used by any other threads without lock?

I implementing a high performance thread safe component, using no lock statements, only volatile and Interlocked are used for performance reasons.

I have volatile reference-type member in a class, that contains thread safe instance. This instance is thread safe only for a couple of operations, and not for another. Because of that and for performance reasons, in some cases i prefer creating new instance instead of updating the original, and it really working faster, especially because i dont using any lock statements.

So the volatile member can be replaced in any time to another instance, the volatile keyword ensures that there will not be any problem with that in multithreaded environment.

This of course working very well, but the only problem with that is the garbage collection of the old instances. When tested my component for performance, i found that it spending too much time in garbage collection the released instances.

Now i searching a way to recycle the old instances. The problem is that i can't just take the old instance when replacing and just reset it's state because there may be another threads that still using this instance and i can't found a way (without lock) that guaranties that noone using this instance anymore.

How can i guaranty that there is no thread that using the old instance without lock statements? (volatile and Interlocked are preferred)

Thanks.

What you are trying to implement here looks so much like reference counting (remember COM?). You probably can do this with increments / decrements - just keep a reference counter right next to your reference.

The only problem with this technique is that it relies on the object consumers to be decent with object usage. This makes the code very fragile.

Another question is that AFAIK the main performance problem with locks is not the lock iteself but rather the memory barrier it implies. The point is that every acces to a volatile variable does the same. In other words I do not thnk you gained anything replacing locks with volatile variables

The problem is that any thread can take a reference to object onto the stack, and then do whatever they want with it. There's no way of preventing this for the non-threadsafe operations without using an overall lock.

Generally, you shouldn't try to work against the .NET garbage collector - it'll be better to find out why GCs are taking so long, and optimize for that (don't create so many instances in the first place, maybe an O(n^2) operation creating lots of instances?) rather than trying to re-use instances in a thread-safe way.

You are asking if something exists that will tell you if it is safe to do an operation on an object in a multi-threaded application. That is the definition of a lock. If using the structure that is provide by .NET is not fast enough, maybe you should consider changing to a complied language that will run faster.

You could ressurect the object from the dead, ie when your objects are finalized you actually make them alive again. This has the benefit, that at this point in their lifecycle, there cannot be any reference to them, otherwise they would have never been applicable for finalize in the first place. For more details look for the "Ressurection" chapter in this article.

Now, if that really buys you any performance, or if it is worth doing it, I can't tell ;-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM