Is it possible to write a class such that other programmers cannot acquire a lock on an instance of the class?
Lock-abuse, if there's a term like that, can be a serious killer. unfortunately, programmers torn between the disastrous forces of delivering thread-safe code and limited knowledge of concurrency, can wreak havoc by adopting the approach of locking instances even when they're invoking operations which really don't require the instance's resources to be blocked
The only way to do this is to ensure that the classes instances are not visible. For example, you could declare is as a private nested class, and make sure that the enclosing class does not leak reference instances.
Basically, if something can get hold of a reference to an instance, there is nothing to stop it from locking it.
Normally, it is sufficient to ensure that the reference to the lock object doesn't leak ... and not worry about the class visibility.
FOLLOW UP - in response to the OP's comments.
You cannot stop someone else's code from taking a lock an instance of one of your classes. But you can design your class so that this won't interfere with your classes internal synchronization. Simply arrange that your class uses a private object (even an Object instance) for synchronizing.
In the more general sense, you cannot stop application programmers from using your classes in ways that you don't like. Other examples I've heard of (here) include trying force people to override methods or provide particular constructors. Even declaring your class fields private won't stop a determined (or desperate) programmer from using reflection to get at them.
But the flip-side is that those things you are trying to prevent might actually not be stupid after all. For example, there could actually be a sound reason for an application to use your class as a lock object, notwithstanding your objection that it reduces concurrency. (And it in general it does, It is just that this may not be relevant in the particular case.)
My general feeling is that is a good idea to document the way your class is designed to be used, and design the API to encourage this. But it is unwise to try to force the issue. Ultimately it is the responsibility of the people who code against your classes to use them sensibly ... not yours.
If a class has members that require protection from concurrent access, locking should be done internally. Otherwise, you're forcing those who use it to understand the details of its implementation when they shouldn't be able to see past its interface.
When creating a new instance, also create a new thread which immediately synchronizes on the instance and goes to sleep (with Thread.sleep()). Any code trying to synchronize on the instance will just deadlock, thus the developer has to rethink his approach.
Disclaimer:
Don't vote me done because my suggestion is insane. I know it is. I am just answering the question. Do not actually do this!!!
Related
I am just trying to come up the use cases where developer may need to use Singleton class . Here they are:-
When we need to maintain the synchronization among resources. For
example in case of logging, multiple threads need to write to single
log file in sequence. Here singleton helps as synchronization is
required among different threads so that they write in single file
in sequence.
When object creation itself is costly which means it time
consuming operation . For example :- hibernate factory creation at
start up. I am not saying this is the case in every situation but
yes in some cases singleton helps here when same state needs to be
shared across application and object creation is costly.
In case of business service objects , singleton helps as it
forces us not to maintain the state of object which in turn makes
code better unit testable.
Is my understanding on the right track?
I was looking for example of singleton in jdk and came across Runtime class and thought why this singleton? As per my understanding reason should be the first one. For example we need synchronization so that two threads doesn't run GC at same instant. Is my logic correct?
Every Java application has a single instance of class Runtime that
allows the application to interface with the environment in which the
application is running.
It feels intuitive that since the environment in which the Java program is executing is one, static thing which is not going to change, Runtime is made singleton.
The number of processors, the total RAM, etc are not going to change even if you spawn more and more threads. Thus, making Runtime a singleton instance optimizes the execution of the program by avoiding having to create an object that contains the same information as 1000 other threads.
This is my understanding of it.
Singletons are evil. They're really global variables in disguise. They're particularly bad for unit tests as once the singleton is loaded by a classloader, it's behaviour is fixed so you can't mock it. Your code will be fixed to call that dependency forever.
A better approach would be to use dependency injection to inject that dependency exactly to where it's needed, or to pass down the dependency through your code to where it's needed.
Have a read of: http://c2.com/cgi/wiki?SingletonsAreEvil
Also you ask yourself why you would want to use a singleton. A singleton means one instance but it really means one instance per classloader. This may or may not be what you really desire for your solution.
I have a producer consumer like pattern where some threads are creating data and periodically passing putting chunks of that data to be consumed by some other threads.
Keeping the Java Memory Model in mind, how do i ensure that the data passed to the consumer thread has full 'visibility'?
I know there are data structures in java.util.concurrent like ConcurrentLinkedQueue that are built specifically for this, but I want to do this as low level as possible without utilizing those and have full transparency on what is going on under the covers to ensure the memory visibility part.
If you want "low level" then look into volatile and synchronized.
To transfer data, you need a field somewhere available to all threads. In your case it really needs to be some sort of collection to handle multiple entries. If you made the field final, referencing, say, a ConcurrentLinkedQueue, you'd pretty much be done. The field could be made public and everyone could see it, or you could make it available with a getter.
If you use an unsynchronized queue, you have more work to do, because you have to manually synchronize all access to it, which means you have to track down all usages; not easy when there's a getter method. Not only do you need to protect the queue from simultaneous access, you must make sure interdependent calls end up in the same synchronized block. For instance:
if (!queue.isEmpty()) obj = queue.remove();
If the whole thing is not synchronized, queue is perfectly capable of telling you it is not empty, then throwing a NoSuchElementException when you try to get the next element. (ConcurrentLinkedQueue's interface is specifically designed to let you do operations like this with one method call. Take a good look at it even if you don't want to use it.)
The simple solution is to wrap the queue in another object whose methods are carefully chosen and all synchronized. The wrapped class, even if it's LinkedList or ArrayList, will now act (if you do it right) like CLQ, and it can be freely released to the rest of the program.
So you would have what is really a global field with an immutable (final) reference to a wrapper class, which contains a LinkedList (for example) and has synchronized methods that use the LinkedList to store and access data. The wrapper class, like CLQ, would be thread-safe.
Some variants on this might be desirable. It might make sense to combine the wrapper with some other high-level class in your program. It might also make sense to create and make available instances of nested classes: perhaps one that only adds to the queue and one that only removes from it. (You couldn't do this with CLQ.)
A final note: having synchronized everything, the next step is to figure out how to unsynchronize (to keep threads from waiting too much) without breaking thread safety. Work really hard on this, and you'll end up rewriting ConcurrentLinkedQueue.
Is it true that if I only use immutable data type, my Java program would be thread safe?
Any other factors will affect the thread safety?
****Would appreciate if can provide an example. Thanks!**
**
Thread safety is about protecting shared data and immutable objects are protected as they are read only. Well apart from when you create them but creating a object is thread safe.
It's worth saying that designing a large application that ONLY uses immutable objects to achieve thread safety would be difficult.
It's a complicated subject and I would recommend you reading Java Concurrency in Practice
which is a very good place to start.
It is true. The problem is that it's a pretty serious limitation to place on your application to only use immutable data types. You can't have any persistent objects with state which exist across threads.
I don't understand why you'd want to do it, but that doesn't make it any less true.
Details and example: http://www.javapractices.com/topic/TopicAction.do?Id=29
If every single variable is immutable (never changed once assigned) you would indeed have a trivially thread-safe program.
Functional programming environments takes advantage of this.
However, it is pretty difficult to do pure functional programming in a language not designed for it from the ground up.
A trivial example of something you can't do in a pure functional program is use a loop, as you can't increment a counter. You have to use recursive functions instead to achieve the same effect.
If you are just straying into the world of thread safety and concurrency, I'd heartily recommend the book Java Concurrency in Practice, by Goetz. It is written for Java, but actually the issues it talks about are relevant in other languages too, even if the solutions to those issues may be different.
Immutability allows for safety against certain things that can go wrong with multi-threaded cases. Specifically, it means that the properties of an object visible to one thread cannot be changed by another thread while that first thread is using it (since nothing can change it, then clearly another thread can't).
Of course, this only works as far as that object goes. If a mutable reference to the object is also shared, then some cases of cross-thread bugs can happen by something putting a new object there (but not all, since it may not matter if a thread works on an object that has already been replaced, but then again that may be crucial).
In all, immutability should be considered one of the ways that you can ensure thread-safety, but neither the sole way nor necessarily sufficient in itself.
Although immutable objects are a help with thread safety, you may find "local variables" and "synchronize" more practical for real world progamming.
Any program where no mutable aspect of program state is accessed by more than one thread will be trivally thread-safe, as each thread may as well be its own separate program. Useful multi-threading, however, generally requires interaction between threads, which implies the existence of some mutable shared state.
The key to safe and efficient multi-threading is to incorporate mutability at the right "design level". Ideally, each aspect of program state should be representable by one immutably-rooted(*), mutable reference to an object whose observable state is immutable. Only one thread at a time may try to change the state represented by a particular mutable reference. Efficient multi-threading requires that the "mutable layer" in a program's state be low enough that different threads can use different parts of it. For example, if one has an immutable AllCustomers data structure and two threads simultaneously attempted to change different customers, each would generate a version of the AllCustomers data structure which included its own changes, but not that of the other thread. No good. If AllCustomers were a mutable array of CustomerState objects, however, it would be possible for one thread to be working on AllCustomers[4] while another was working on AllCustomers[9], without interference.
(*) The rooted path must exist when the aspect of state becomes relevant, and must not change while the access is relevant. For example, one could design an AddOnlyList<thing> which hold a thing[][] called Arr that was initialized to size 32. When the first thing is added, Arr[0] would be initialized, using CompareExchange, to an array of 16 thing. The next 15 things would go in that array. When the 17th thing is added, Arr[1] would be initialized using CompareExchange to an array of size 32 (which would hold the new item and the 31 items after it). When the 49th thing is added, Arr[2] would be initialized for 64 items. Note that while thing itself and the arrays contained thereby would not be totally immutable, only the very first access to any element would be a write, and once Arr[x][y] holds a reference to something, it would continue to do so as long as Arr exists.
Java 6 API question. Does calling LockSupport.unpark(thread) have a happens-before relationship to the return from LockSupport.park in the just-unparked thread? I strongly suspect the answer is yes, but the Javadoc doesn't seem to mention it explicitly.
I have just found this question because I was asking myself the same thing. According to this article by Oracle researcher David Dice, the answer seems to be no. Here's the relevant part of the article:
If a thread is blocked in park() we're guaranteed that a subsequent
unpark() will make it ready. A perfectly legal but low-quality
implementation of park() and unpark() would be empty methods, in which
the program degenerates to simple spinning. An in fact that's the
litmus test for correct park()-unpark() usage.
Empty park() and unpark() methods do not give you any happens-before relationship guarantees, so for your program to be 100% portable, you should not rely on them.
Then again, the Javadoc of LockSupport says:
These methods are designed to be used as tools for creating
higher-level synchronization utilities, and are not in themselves
useful for most concurrency control applications. The park method is
designed for use only in constructions of the form:
while (!canProceed()) { ... LockSupport.park(this); }
Since you have to explicitly check some condition anyway, which will either involve volatile or properly synchronized variables, the weak guarantees of park() should not actually be problem, right?
If it isn't documented as such then you CANNOT rely on it creating a happens before relationship.
Specifically LockSupport.java in Hotspot code simply calls Unsafe.park and .unpark!
The happens-before relationship will generally come from a write-read pair on a volatile status flag or something similar.
Remember, if it isn't documented as creating a happens-before relationship then you must treat it as though it does not even if you can prove that it does on your specific system. Future systems and implementations may not. They left themselves that freedom for good reason.
I have looked though the JDK code and it looks like LockSupport methods are normally called outside of synchronization blocks. So, your assumption seems to be correct.
I was reading some of the concurrency patterns in Brian Goetze's Java Concurrency in Practice and got confused over when is the right time to make the code thread safe.
I normally write code that's meant to run in a single thread so I do not worry too much about thread safety and synchronization etc. However, there always exists a possibility that the same code may be re-used sometime later in a multi-threaded environment.
So my question is, when should one start thinking about thread safety? Should I assume the worst at the onset and always write thread-safe code from the beginning or should I revisit the code and modify for thread safety if such a need arises later ?
Are there some concurrency patterns/anti-patterns that I must always be aware of even while writing single-threaded applications so that my code doesn't break if it's later used in a multi-threaded environment ?
You should think about thread safety when your code will be used in a multithreaded environment. There is no point in tackling the complexity if it will only be run in a singlethreaded environment.
That being said, there are simple things you can do that are good practices anyway and will help with multithreading:
As Josh Bloch says, Favor Immutability. Immutable classes are threadsafe almost by definition;
Only use data members or static variables where required rather than a convenience.
Making your code thread safe can be as simple as adding a comment that says the class was not designed for concurrent use by multiple threads. So, in that sense: yes, all of your classes should be thread safe.
However, in practice, many, many types are likely to be used by only a single thread, often only referenced as local variables. This can be true even if the program as a whole is multi-threaded. It would be a mistake to make every object safe for multi-threaded access. While the penalty may be small, it is pervasive, and can add up to be a significant, hard-to-fix performance problem.
I advise you to obtain a copy of "Effective Java", 2nd Ed. by Joshua Bloch. That book devotes a whole chapter to concurrency, including a solid exploration of the issue of when (and when not) to synchronize. Note, for example, the title of item 67 in "Effective Java": 'Avoid excessive synchronization', which is elaborated over five pages.
As was stated previously, you need thread safety when you think your code will be used in a multithreaded environment.
Consider the approach taken by the Collections classes, where you provide a thread-unsafe class that does all its work without using synchronize, and you also provide another class that wraps the unsynchonized class and providing all of the same public methods but making them synchronize on the underlying object.
This gives your clients a choice of using the multi-threaded or the single-threaded version of your code. It may also simplify your coding by isolating all of the threading/locking logic in a separate class.