Synchronized on String.class - java

In one of my existing Spring Java code some one has written code like below :
I am not sure why we need to synchronize String class for thread safety. Can anyone suggest?
public class MyTimerTask extends TimerTask{
#Autowired
MyService service;
public void run(){
synchronized(String.class){
service.callSomeMethod();
}
}
}

There is no need to use String.class. You can synchronize on any object, including any Class instance. Using the String class is a poor choice, but it would work.
The reason it's a poor choice is because (a) it's public—your code could interact in unexpected ways with some other part of a large program where some other programmer also decided to write synchronized(String.class)—But more important is (b) it's completely demented. It will make other programmers waste time trying to understand what you did and why you thought it was smart to do it.
There's maybe a third reason (c) but hard to tell without seeing more of your code. Reason (c) would be that String.class is a static instance, and if you're using that one global object to synchronize many different MyTimerTask instances, and if those instances do not interact with each other through shared, static variables, then using the one global synchronization object probably adds an un-necessary performance bottleneck.
This would be better (takes care of reasons (a) and (b)):
public class MyTimerTask extends TimerTask{
private final static Object mutex = new Object();
...
public void run(){
synchronized(mutex){
service.callSomeMethod();
}
}
}
Or, depending on how MyTimerTask is used, removing static from the declaration of mutex might be better still (takes care of reason (c)).

Related

How to avoid creating Thread hostile classes in Java

In effective java 2nd Edition Item 70 Josh Bloch explained about thread hostile classes
This class is not safe for concurrent use even if all method
invocations are surrounded by external synchronization. Thread
hostility usually results from modifying static data without
synchronization
Can Someone explain me with example how it's impossible to achieve thread safety by external synchronization if the class modifies shared static data without internal synchronization?
The citation assumes the synchronization of every call to the class method on the same object instance. For example, consider the following class:
public class Test {
private Set<String> set = new TreeSet<>();
public void add(String s) {
set.add(s);
}
}
While it's not thread-safe, you can safely call the add method this way:
public void safeAdd(Test t, String s) {
synchronized(t) {
t.add(s);
}
}
If safeAdd is called from multiple threads with the same t, they will be mutually exclusive. If the different t is used, it's also fine as independent objects are updated.
However consider that we declare the set as static:
private static Set<String> set = new TreeSet<>();
This way even different Test objects access the shared collection. So in this case the synchronization on Test instances will not help as the same set may still be modified concurrently from different Test instances which may result in data loss, random exception, infinite loop or whatever. So such class would be thread-hostile.
Can Someone explain me with example how it's impossible to achieve thread safety by external synchronization if the class modifies shared static data without internal synchronization?
It's not impossible. If the class has methods that access global (i.e., static) data, then you can achieve thread-safety by synchronizing on a global lock.
But forcing the caller to synchronize threads on one global lock still is thread-hostile. A big global lock can be a serious bottleneck in a multi-threaded application. What the author wants you to do is design your class so that it would be sufficient for the client to use a separate lock for each instance of the class.
Perhaps a contrived example, but this class is impossible to synchronize externally, because the value is accessible from outside the class:
public class Example {
public static int value;
public void setValue(int newValue) {
this.value = newValue;
}
}
However you synchronize invocation of the setter, you can't guarantee that some other thread isn't changing value.

Decorator for Java class with final methods

I have a (Java) class, WindowItem, that has a problem: One of the methods is not thread-safe. I can't fix WindowItem, because it's part of an external framework. So I figured I implement a Decorator for it, that has a "synchronized" keyword on the method in question.
The Decorator extends WindowItem and will also contain WindowItem. Following the Decorator pattern, I create methods in the Decorator that call the WindowItem it contains.
However, WindowItem has a few final methods, that I cannot override in the Decorator. That breaks the transparency of the Decorator. Let's make this explicit:
public class WindowItem {
private List<WindowItem> windows;
public Properties getMethodWithProblem() {
...
}
public final int getwindowCount() {
return windows.size();
}
}
public class WindowItemDecorator extends WindowItem {
private WindowItem item;
public WindowItemDecorator(WindowItem item) {
this.item = item;
}
# Here I solve the problem by adding the synchronized keyword:
public synchronized Properties getgetMethodWithProblem() {
return super.getMethodWithProblem();
}
# Here I should override getWindowCount() but I can't because it's final
}
In my own code, whenever I have to pass a WindowItem somewhere, I wrapped it in a decorator first: new WindowItemDecorator(item) -- and the thread-safety problem disappears. However, if my code calls getwindowCount() on a WindowItemDecorator, it will always be zero: It executes getWindowCount() on the superclass instead of the "item" member.
So I would say the design of WindowItem (the fact that it has public final methods) makes it impossible to create a Decorator for this class.
Is that correct, or am I missing something?
In this case I might be able to keep a copy of the list of windows in the decorator, and keep it in sync, and then the result of getWindowCount() would be correct. But in that case, I prefer to fork and patch the framework...
How about not thinking of the problem this way? Why not just handle the threading issues in your code, without assuming thread-safety of WindowItem.
// I personally prefer ReadWriteLocks, but this sounds like it will do...
synchronized (windowItem) {
windowItem.getMethodWithProblem();
}
And then submit an RFE with the package maintainer to better support thread safety.
Indeed, if the class isn't designed to be thread safe, it is unlikely that a few synchronized keywords are going to truly fix things. What somebody means by "thread safe" is always relative ;-)
(Incidentally, WindowItem is definitely NOT thread safe as it is using List instead of explicitly using a "thread ready" variant Correct way to synchronize ArrayList in java - there are also no guarantees that the List is being accessed in a thread safe manner).
Perhaps you could employ the Delegation Pattern, which would work nicely if the WindowItem class implements an interface defining all the methods you care about. Or if it doesn't break too much of your existing code to refer to this delegated class rather than WindowItem.
The answer to your question is yes, you can't override final methods, meaning that it's not possible to create a decorator for this class.
If you can override the method that has the problem, and solve the problem by synchronizing the method, you could just leave it at that. That is, just use your subclass, and not use the decorator pattern.
A coworker had an idea that I think can solve the problem. I can keep the state of the superclass and the state of the "item" member in sync by looking at all methods that modify the List windows. There are a few: addWindow, removeWindow. Instead of calling just "item.addWindow(...)" in the decorator, I call addWindow on the superclass as well:
Normal decorator:
public void addWindow(WindowItem newItem) {
item.addWindow(newItem);
}
In this case I do:
public void addWindow(WindowItem newItem) {
super.addWindow(newItem);
item.addWindow(newItem);
}
That keeps the state in sync and the return values of the final methods correct.
This is a solution that can work or not work depending on internals of the class being decorated.

Multiple Threads calling static helper method

I have a web application running on Tomcat.
There are several calculations that need to be done on multiple places in the web application. Can I make those calculations static helper functions? If the server has enough processor cores, can multiple calls to that static function (resulting from multiple requests to different servlets) run parallel? Or does one request have to wait until the other request finished the call?
public class Helper {
public static void doSomething(int arg1, int arg2) {
// do something with the args
return val;
}
}
if the calls run parallel:
I have another helper class with static functions, but this class contains a private static member which is used in the static functions. How can I make sure that the functions are thread-safe?
public class Helper {
private static SomeObject obj;
public static void changeMember() {
Helper.obj.changeValue();
}
public static String readMember() {
Helper.obj.readValue();
}
}
changeValue() and readValue() read/change the same member variable of Helper.obj. Do I have to make the whole static functions synchronized, or just the block where Helper.obj is used? If I should use a block, what object should I use to lock it?
can i make those calculations static helper functions? if the server has enough processor cores, can multiple calls to that static function (resulting from multiple requests to different servlets) run parallel?
Yes, and yes.
do i have to make the whole static functions synchronized
That will work.
or just the block where Helper.obj is used
That will also work.
if i should use a block, what object should i use to lock it?
Use a static Object:
public class Helper {
private static SomeObject obj;
private static final Object mutex = new Object();
public static void changeMember() {
synchronized (mutex) {
obj.changeValue();
}
}
public static String readMember() {
synchronized (mutex) {
obj.readValue();
}
}
}
Ideally, though, you'd write the helper class to be immutable (stateless or otherwise) so that you just don't have to worry about thread safety.
You should capture the calculations in a class, and create an instance of the class for each thread. What you have now is not threadsafe, as you are aware, and to make it threadsafe you will have to synchronize on the static resource/the methods that access that static resource, which will cause blocking.
Note that there are patterns to help you with this. You can use the strategy pattern (in its canonical form, the strategy must be chosen at runtime, which might or might not apply here) or a variant. Just create a class for each calculation with an execute method (and an interface that has the method), and pass a context object to execute. The context holds all the state of the calculation. One strategy instance per thread, with its context, and you shouldn't have any issues.
If you don't have to share it you can make it thread local, then it doesn't have to be thread safe.
public class Helper {
private static final ThreadLocal<SomeObject> obj = new ThreadLocal<SomeObject>() {
public SomeObject initialValue() {
return enw SomeObject();
}
}
public static void changeMember() {
Helper.obj.get().changeValue();
}
public static String readMember() {
Helper.obj.get().readValue();
}
}
I'll sum up here what has been said in the comments to the Matt Ball's answer, since it got pretty long at the end and the message gets lost: and the message was
in a shared environment like a web/application server you should try very hard to find a solution without synchronizing. Using static helpers synchronized on static object might work well enough for stand alone application with a single user in front of the screen, in a multiuser/multiapplication scenario doing this would most probably end in a very poor performance - it would effectively mean serializing access to your application, all users would have to wait on the same lock. You might not notice the problem for a long time: if the calculation are fast enough and load is evenly distributed.
But then all of a sudden all your users might try to go through the calculation at 9am and you app will stop to work! I mean not really stop, but they all would block on the lock and make a huge queue.
Now regardless the necessity of a shared state, since you originally named calculations as subject of synchronization: do their results need to be shared? Or are those calculations specific to a user/session? In the latter case a ThreadLocal as per Peter Lawrey would be enough. Otherwise I'd say for overall performance it would be better to duplicate the calculations for everybody needing them in order not to synchronize (depends on the cost).
Session management should also be better left to the container: it has been optimized to handle them efficiently, if necessary including clustering etc. I doubt one could make better solution without investing lot of work and making lots of bugs on the way there. But as Matt Ball has stated it should be better asked separately.
In the first case you don't have to worry about threading issues, because the variables are local to each thread. You correctly identify the problem in the second case, though, because multiple threads will be reading/writing the same object. Synchronizing on the methods will work, as would synchronized blocks.
For the first part:
Yes, these calls are independent and run in parallel when called by different threads.
For the last part:
Use synchronize blocks on the concurrent object, a dummy object or class object. Be aware of cascaded synchronize blocks. They can lead into dead locks when acquired in different order.
If you are worried about synchronization and thread safety, don't use static helpers. Create a normal class with your helper methods and create an instance upon servlet request. Keep it simple :-)

Protecting a static class variable

I have a fairly trivial static variable question. I'm building out a solution that loosely follows the path or RMI. On my server, I have a ComputeEngine class that will execute 'Tasks' (class instances with an 'execute' method). However, the ComputeEngine will contain a global variable that will need to be accessed by different tasks, each executing in its own thread. What's the best way to give access to this? I want to keep everything as loosely coupled as possible. The shared global static variable in my ComputeEngine class will be a List. Should I have a getter for this static variable? I will have a read/write lock in my ComputeEngine class to give access to my global List. This too will be static and will need to be shared. I'm looking for best practice on how to provide access to a global static variable in a class.
If you want to decouple it, the best way is to pass a callback object when you create the Task.
interface FooListManipulator {
void addFoo( Foo f );
List<Foo> getFooList();
}
class Task {
private FooListManipulator fooListManipulator;
public Task( FooListManipulator fooListManipulator ) {
this.fooListManipulator = fooListManipulator;
}
}
This way the Task itself doesn't have to assume anything about who created it and how the list is stored.
And in your ComputeEngine you will do something like this:
class ComputeEngine {
private static List<Foo> fooList;
class Manipulator implements FooListManipulator {
public void addFoo( Foo f ) {
synchronized( fooList ) {
fooList.add( f );
}
}
public List<Foo> getFooList() {
return Collections.unmodifiableList( fooList );
}
}
private Task createTask() {
return new Task( new Manipulator() );
}
}
If you want to change the storage of fooList later (which you should really consider, as static global variables aren't a great idea), Task will remain unchanged. Plus you will be able to unit test Task with a mock manipulator.
I'm looking for best practice on how
to provide access to a global static
variable
By best practices, you shouldn't have such variables.
Should I have a getter for this static
variable? I will have a read/write
lock in my ComputeEngine class to give
access to my global List.
No, you shouldn't provide such getter. Just addTask(Task task) or execute(task) method. Method synchronization will be workable solution.
Nooooooooooooooooooooooooooooooooooooooooooooooooooo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Static mutables are Bad, and dressing it up as Singletons just make matters worse. Pass objects through constructors as necessary. And give objects sensible behaviour.
In the case of RMI, by default you are loading untrusted code from wherever directed by the client (top tip, when using RMI, use -Djava.rmi.server.useCodebaseOnly=true). As a global static, this code can fiddle with your server state (assuming in an accessible class loader, etc).
don't return your list from the getter, as you won't know what people will do with it (they may add things and break your locking). So do this:
static synchronized List getTheList() {
return new ArrayList(theList);
}
and only implement the getter if anyone actually needs it
don't implement any setters; instead implement addItemToList() and removeItemToList()
other than that, having a global static variable is frowned upon...
I have several recommendations for you:
Your "Task" sounds like a Runnable, change "execute" to "run" and you get a lot of stuff for free. Like all the awesome classes in java.util.concurrent.
Make ComputeEngine itself a Singleton via the technique in this post. To be clear, use the "enum" approach from Josh Bloch (2nd answer on that question).
Make your List a member of ComputeEngine
Tasks use ComputeEngine.saveResult(...), which modifies the List.
Consider using java.util.concurrent.Executors to manage your pool of Tasks.
Going after #biziclop answer but with other separation)
You can separate your code in next parts.
interface Task {
void execute();
}
public final class TaskExecutor{
TaskExecutor(List<Task> tasks){}
void addTask(Task task){synchronized(tasks){tasks.add(task);}}
}
Than,
public class SomeTaskAdder {
SomeTaskAdder(TaskExecutor executor){}
void foo(){
executor.addTask(new GoodTask(bla-bla));
}
}
public class SomeTasksUser {
SomeTasksUser(List<Task> tasks){synchronized(tasks){bla-bla}}
}
than, you should create your objects with some magic constructor injection)
Everyone seems to be asserting you're using the List to keep a queue of Tasks, but I don't actually see that in your question. But if it is, or if the manipulations to the list are otherwise independent — that is, if you are simply adding to or removing from the list as opposed to say, scanning the list and removing some items from the middle as a part of the job — then you should consider using a BlockingQueue or QueueDeque instead of a List and simply leveraging the java.util.concurrent package. These types do not require external lock management.
If you require in earnest a List which is concurrently accessed by the each job, where the reads and writes to the list not independent, I would encapsulate the part of the processing which does this manipulation in a singleton, and use an exclusive lock to have each thread make use of the list. For instance, if your list contains some sort of aggregate statistics which are only a part of the process execution, then I would have my job be one class and a singleton aggregate statistics be a separate job.
class AggregateStatistics {
private static final AggregateStatistics aggregateStatistics =
new AggregateStatistics();
public static AggregateStatistics getAggregateStatistics () {
return aggregateStatistics;
}
private List list = new ArrayList ();
private Lock lock = new ReentrantLock();
public void updateAggregates (...) {
lock.lock();
try {
/* Mutation of the list */
}
finally {
lock.unlock();
}
}
}
Then have your task enter this portion of the job by accessing the singleton and calling the method on it which is managed with a lock.
Never pass a collection which into a concurrent environment, it will only cause you problems. You can always pass around an immutable "wrapper" though if it's really suitable, by using java.util.Collections.unmodifiableList(List) and similar methods.

Difference Between Using Static Fields That Uses Getter And Setter And Static Fields That Are Declared Public

I searched about best ways to hold/share data that are to be used globally and as expected I found a lot of answers. One of the ways that caught my attention is by using static fields. However, the static field way stated there was like this:
public class DataHolder
{
private static String dataString;
public static String getDataString
{
return dataString;
}
public static void setString(String dataString)
{
this.dataString = dataString;
}
}
But I am always doing it this way:
public class DataHolder
{
public static String dataString;
}
I am just wondering isn't the latter much more easier than the first? Because I don't have to set any getter and setter methods. And I don't see any difference between the two. So why not recommend the second one?
I was also told before that doing my way would result to memory leak problem sometimes. But won't the first solution lead to memory leak issues?
Your question about memory leaks
I want to start off by saying there will be no memory leak issues here. In fact, it would be exactly the opposite of memory leaks in both cases (they're the same in this respect). You can have only one instance of a String for the DataHolder class (since it is static, it does not belong to any DataHolder instance).
Imagine it was not static:
public class DataHolder
{
String dataString;
}
this means that for every time you do new DataHolder(), you will have a separate instance of a String. With your static dataString, there will only ever be one instance.
Getters and Setters and Synchronization
The reason why your implementation is bad is because it is not thread safe, as Piyush Mittal pointed out. He didn't get into any details though, so I want to add my two cents.
You can't say that just because you only expect it to be used in a single thread that it will only be used in a single thread. The Swing thread is a great example of this, where there is only ever one thread that handles the UI. You would expect in this case that only one thread exists, and it is OK to do this. However, any background work must be done in a SwingWorker thread, so creating a SwingWorker thread here to do that will provide a data race opportunity because now there are two threads. You should always have getters and setters for static variables for this reason.
That being said, the code snippet you provided is exactly the same between your two examples (with the small difference of generating a new stack frame for the new function) because there is no synchronization. You want to do this:
public class DataHolder{
private static String dataString;
public static String getDataString(){
synchronized(DataHolder.class){
return DataHolder.dataString;
}
}
public static void setString(String dataString){
synchronized(DataHolder.class){
DataHolder.dataString = dataString;
}
}
}
I did change some things about your code. The first and most obvious is there is no this keyword used for static variables. As I hinted at before, because its static it does not belong to any instance. 'this' is not a thing in a static context.
The other thing I did was put the synchronized inside of the method. I did this for two reasons. The first was preference; some people prefer to keep synchronized out of the function signature so it is obfuscated from the caller, so they don't make assumptions because the function is synchronized. That is preference. The other reason I did this, is because I wanted to make it obvious that when you synchronize a function in the signature, this is how it actually will look 'under the hood'. As mentioned, since there is no 'this', it will actually synchronize on the class itself.
I think you could probably use some reading about the static keyword. I think your confusion is coming from the fact that you don't understand it, and you're trying to answer a question about getters and setters for the static variable before understanding statics themselves. Here is a link I found with a quick google search that might get you started:
http://www.javatpoint.com/static-keyword-in-java
don have much idea about memory leaks.
But: multiple parallel requests - multiple threads, you surely have a threading issue here - this is not thread-safe unless you take care of (e.g. use synchronized).
I would much prefer the getter/setters, rather than a public field.
That sort of encapsulation allows you to modify the types of properties without breaking the code of those using it.
What if you decided to create a Data type, rather than storing it as a String? (for increased type safety).
With a public field, it's not possible. But using getter/setters, you can perform the parsing needed to allow this:
class SomeClass {
private static Data data;
public static void setData(String data) {
data = new Data(data);
}
public static String getData() {
return data.toString();
}
}
class Data {
private String data;
public Data(String data) {
this.data = data;
}
public String toString() {
return data;
}
}
It's not a memory leak problem, as it has nothing to do with allocating memory. There may be some inconsistency between threads when using that data, since it is not thread-safe, but any leaking will not be a result of using static, rather than not multithreading properly.
Rather than accessing something globally, you should pass the dependency to where it's needed. For example, a method that uses a global variable. Pass the value to it through the parameters. This is called dependency injection.

Categories

Resources