I need to use (at the moment) some java apis that -unfortunatelly- can be "configured" only via jvm properties.
I understand that this can affect multithreading, since it can be the case that one thread modifying the properties can affect the others running.
So I thought to do this inside a synchronized method e.g.
public static sychronized void someMethod(){
Security.setProperty("responderURL",IP);
//do code here
}
It seems it is ok, but I was wondering if there any pitfalls on this and whether there is any kind of design pattern for cases like these?
Thanks
When you create a synchronized static method, it synchronizes on the class that the method is in. This means that only one method in that class will be able to run at a time. If that solves your problem, then perfect.
However, if any other method in the JVM modifies those properties outside of that class or outside of a method that's synchronized on the class, then your efforts won't have any effect.
You dont need to synchronize , System.setProperty is already synchronized method, and although System.getProperty is not synchronized, Properties class extends HashTable which has syncronized method to access its key-value pairs.As a result, you dont need to do worry about synchronizing issues..
EDIT :
Some clarifications about my answer ;
1.If your method should work as an atomic unit, it should be synchronized , such as ;
public static sychronized void someMethod(){
if (System.getProperty("responderURL")==null)
System.setProperty("responderURL",IP);
//do code here
//some code
URL url = new URL(System.getProperty("responderURL"),8080,"test.txt");
}
You should synchronized your method, because while Thread 1 is checking responderURL property , Thread 2 could set this property.
2.But if your method sets only responderURL property, and its functionality does not depend respondrURL property current value, you dont need to synchronize your method..
public static void someMethod(){
System.setProperty("responderURL",IP);
//do code here
//some code
URL url = new URL(IP,8080,"test.txt");
}
Using synchronized won't help you here. The only thing synchronized does in your example is ensure that two threads cannot call your synchronized method simultaneously.
public class Foo {
public static synchronized void bar() {
//...
}
}
is exactly the same as
public class Foo {
public static void bar() {
synchronized (Foo.class) {
//...
}
}
}
i.e. only code that can see Foo.class and synchronizes on it will be affected by your synchronization. Since code in whatever libraries you are calling obviously does not know about Foo.class, synchronizing on it will not have any effect.
If you want to guarantee that these system properties are set before any code runs which might read the values can possibly run, the most bulletproof way is to pass them as -D arguments to the java command which starts the JVM, e.g.
java -DresponderURL=http://foo.bar.
The next best approach is, as you are doing, set the properties in some method called early in VM startup. It is always preferable to do it with command-line arguments if possible, though, for this reason: If any such properties are read in static{} blocks in the libraries you're using, those blocks may run before your code does, because Java's bytecode verifier may cause those classes to be initialized before your code does anything that calls them (you can avoid this by passing -Xverify:none to the Java command, but if you can do that, you might as well just set the system properties there anyway).
If this is one time configuration, you do this inside a static initialization block. If not, what you have is the classic reader-writer problem. The java.util.concurrent javadocs have some good sample solutions.
Related
I have a class from an external API and I want to create an instance of it and access that object's methods from different threads. My questions are as comments in the following code:
import java.util.concurrent.Executors;
public class ThreadSafetyQuestion {
static class ExternalAPIObject {
void method(){
}
}
private static volatile ExternalAPIObject obj;
static synchronized ExternalAPIObject syncGetObject(){
return obj;
}
public static void main(String[] args) {
Executors.newSingleThreadExecutor().submit(()-> {
ThreadSafetyQuestion.syncGetObject().method();//Is this thread safe?
ExternalAPIObject externalAPIObject = ThreadSafetyQuestion.syncGetObject();
//do some other stuff
externalAPIObject.method();//I doubt this is thread safe. How can I access this method from multiple threads in a safe way?
});
}
}
You are looking at this from the wrong perspective. Thread safe means: when more than one thread invokes these methods nothing bad happens. It is really simple: when method() does manipulate "internal data" without any form of synchronisation - then having more than one thread call method() on the same object can result in a problem.
Thus: all the things that you put up in your question do not matter!
The only thing that matters: what exactly do these methods do that you are invoking?! In other words: there is no point in putting up a singleton to call methods in different threads. Or making the object reference volatile. All these ideas add zero in regards of making things "thread safe". Because you still allow method() to be called on the same object by different threads.
What you have to do instead: carefully check what exactly the methods you are invoking are doing.
And in case you don't want to go there: then create a single singleton that simply delegates calls to method() - but that has its methods marked as synchronized.
So: if you don't know anything about the external API - then one conservative approach is to make sure to always all its methods sequentially. Of course that can affect performance in very negative ways.
Long story short: it seems you are lacking basic understanding of multithreading concepts in Java. Don't go for trial/error then - rather step back and study this topic in depth! Seriously: multi-threading errors are subtle, they often go unnoticed for days or months. The first step in avoiding them: knowing what you are doing (instead of throwing some keywords at a problem that you somehow read about having this or that effect).
Can I change my code from:
class Sample{
private Object _lock=new Object();
public void someMethod(){
synchronized(_lock){
doSomething();
}
}
}
to:
class Sample{
private ISchedulingRule _lock=new SomeSchedulingRule();
public void someMethod(){
try{
Job.getManager().beginRule(_lock);
doSomething();
}finally{
Job.getManager().endRule(_lock);
}
}
}
I'm reading "java concurrency in practice", and they say if I wanna use some explicit lock, I have to guarantee the memory visibility.
So the question is:
If I can guarantee the memory visibility, can I use the code at bottom to replace the code at top(replace intrinsic synchronization with eclipse IJobManager.beginRule and IJobManager.endRule)
Assuming the source code I found here is up to date, you can check that the beginRule method calls implicitJob.begin which has a large synchronized(this) block inside.
If your only goal is to achieve synchronization then the answer is yes.
That said, there are some (hidden) gotchas that you need to be aware of. Since JobManager is designed to prevent dead-locks to some extent, then there are somewhat strict rules for using and defining nested rules (a limitation that Java synchronized blocks don't have). There is no public API for checking whether a thread is holding a rule/lock or not. Also, beginRule cannot be canceled by calling interrupt on waiting thread. To name a few.
I just found a web tutorial on concurrency which makes the following statement:
Well, it turns out that a contract of the Lock interface is that it provides the same >memory barrier behaviour as synchronized.
That's referring to the "Lock" interface in java.util.concurrent. I don't know whether it applies to the ISchedulingRule interface which you show here.
I am just working through some examples from my text book, writing the code in Eclipse to figure it out.
This is the code for the method I have a question about:
public void run() {
//Get the lock before entering the loop
synchronized(getClass()) {
for (int i =0; i<N; i++) {
System.out.println(getName() + " is tired");
try{
Thread.currentThread().sleep(DELAY);
} catch (InterruptedException e) {}
System.out.println(getName() + " is rested");
}
On line the line with:
Thread.currentThread().sleep(DELAY)
Eclipse gives a warning: "The static method sleep(long) from the type Thread should be accessed in a static way". Eclipse suggests the following solution:
Thread.currentThread();
Thread.sleep(DELAY);
I don't understand why it makes a difference (if it really does). Can someone please explain?
sleep() is a static method and causes the current thread to sleep for the specified amount of time. Thus the currentThread() call is superfluous, and can potentially be confusing since it almost implies that you could make another thread sleep by using similar code (you can't).
The best way to write that code is simply:
Thread.sleep(DELAY);
Code in question has nothing to do with threads. Eclipse just says that you should access static method sleep directly via class name, not via instanse: Thread.sleep(DELAY).
Any static method static ... f() of class C should be accessed as C.f() for clarity (and brevity).
The Thread.sleep() is already a static method and affects the current thread. There is no need to call currentThread().
Thread.delay is a static method. It doesn't require an instance to invoke it - you can just say Thread.delay().
Thread.currentThread() returns you an reference to the current thread. You can invoke a static method on it, but you don't strictly need the reference and it's not used at all. You could equally do this:
new Thread().delay(100);
... and it would still make the current thread sleep - not the thread that we just created.
So eclipse is telling you that the better, less confusing way is Thread.delay(100).
Correct me if I'm wrong but the warning probably is "The static method ... should be accessed in a static way" (not ... should be accessed in a non-static way).
In fact it is confusing to call
someThread.sleep(1000)
because as Thread.sleep() is a static method in is not called "against" someThread but on the current Thread.
So the message says "access static methods in a static way" :)
It does not make any difference in execution. However second option Thread.sleep() is more readable as user does not get confused thinking its an instance method.
By accesing the method as Thread.currentThread().sleep() it gives the impression that it is an instance method, to avoid confusion, Eclipse suggests you access static methods through the owner class and by this make evident that they are, in fact, static.
As Victor Sorokin wrote the warning has nothing to do with the example code with Threads. Here is another example where, in Eclipse, we get the same compiler warning:
OptionBuilder.withArgName(PROPERTY_ARG).hasArg(true).isRequired(false).create(PROPERTY_ARG_OPTION);
This is using the Apache Commons CLI library. OptionBuilder uses the 'fluent' builder pattern. The only way I see to fix the warning is use the recommended Eclipse hint, that breaks the line into multiple statements, or prepend an annotation to ignore the warning.
Thread currentThread = Thread.currentThread();
currentThread.wait(DELAY);
Suppose I have a Utility class,
public class Utility {
private Utility() {} //Don't worry, just doing this as guarantee.
public static int stringToInt(String s) {
return Integer.parseInt(s);
}
};
Now, suppose, in a multithreaded application, a thread calls, Utility.stringToInt() method and while the operation enters the method call, another thread calls the same method passing a different s.
What happens in this case? Does Java lock a static method?
There is no issue here. Each thread will use its own stack so there is no point of collision among different s. And Integer.parseInt() is thread safe as it only uses local variables.
Java does not lock a static method, unless you add the keyword synchronized.
Note that when you lock a static method, you grab the Mutex of the Class object the method is implemented under, so synchronizing on a static method will prevent other threads from entering any of the other "synchronized" static methods.
Now, in your example, you don't need to synchronize in this particular case. That is because parameters are passed by copy; so, multiple calls to the static method will result in multiple copies of the parameters, each in their own stack frame. Likewise, simultaneous calls to Integer.parseInt(s) will each create their own stack frame, with copies of s's value passed into the separate stack frames.
Now if Integer.parseInt(...) was implemented in a very bad way (it used static non-final members during a parseInt's execution; then there would be a large cause for concern. Fortunately, the implementers of the Java libraries are better programmers than that.
In the example you gave, there is no shared data between threads AND there is no data which is modified. (You would have to have both for there to be a threading issue)
You can write
public enum Utility {
; // no instances
public synchronized static int stringToInt(String s) {
// does something which needs to be synchronised.
}
}
this is effectively the same as
public enum Utility {
; // no instances
public static int stringToInt(String s) {
synchronized(Utility.class) {
// does something which needs to be synchronised.
}
}
}
however, it won't mark the method as synchronized for you and you don't need synchronisation unless you are accessing shared data which can be modified.
It should not unless specified explicitly. Further in this case, there wont be any thread safety issue since "s" is immutable and also local to the method.
You dont need synchronization here as the variable s is local.
You need to worry only if multiple threads share resources, for e.g. if s was static field, then you have to think about multi-threading.
While discussing a Java synchronization question, someone made a comment that the following snippets are not equivalent (and may compile to different bytecodes):
public synchronized void someMethod() {
//stuff
}
and
public void someMethod() {
synchronized (this) {
//stuff
}
}
Are they equivalent?
They are equivalent in function, though the compilers I tested (Java 1.6.0_07 and Eclipse 3.4) generate different bytecode. The first generates:
// access flags 33
public synchronized someMethod()V
RETURN
The second generates:
// access flags 1
public someMethod()V
ALOAD 0
DUP
MONITORENTER
MONITOREXIT
RETURN
(Thanks to ASM for the bytecode printing).
So the difference between them persists to the bytecode level, and it's up to the JVM to make their behavior the same. However, they do have the same functional effect - see the example in the Java Language Specification.
It should be noted, that if the method is overridden in a subclass, that it is not necessarily synchronized - so there is no difference in that respect either.
I also ran a test to block a thread trying access the monitor in each case to compare what their stack traces would look like in a thread dump, and they both contained the method in question, so there is no difference there either.
I made the original comment that the statements are identical.
In both cases, the first thing that happens is that the calling thread will try to acquire the current object's (meaning, this') monitor.
I don't know about different bytecode, I'll be happy to hear the difference. But in practice, they are 100% identical.
EDIT: i'm going to clarify this as some people here got it wrong. Consider:
public class A {
public synchronized void doStuff()
{
// do stuff
}
}
public class B extends A {
public void doStuff()
{
// do stuff
// THIS IS OVERRIDE!
}
}
In this case doStuff() in class B still overrides doStuff() in class A even though it is not synchronized.
Synchronized keyword is never part of the contract! Not for subclasses, not for interfaces, not for abstract classes.
I made the original comment. My comment was that they are logically equivalent, but compile to different bytecode.
I didn't add anything else to justify it at the time because there's not much to justify really-- they just do compile to different bytecode. If you declare a method as synchronized, then that synchronization is part of the method's definition. A synchronized block within a method isn't part of the method's definition, but instead involves separate bytecodes to acquire and release the monitor, as one of the posters above has illustrated. Strictly speaking, they're slightly different things, though to the overall logic of your program, they're equivalent.
When does this matter? Well, on most modern desktop VMs, hardly ever. But for example:
a VM could in principle make optimisations in one case but not the other
there are some JIT compiler optimisations where the number of bytecodes in the method is taken as a criterion for what optimisations to make
a VM without a JIT compiler (admittedly few nowadays, but maybe on an older mobile device?) will have more bytecodes to process on each call
Yes. Using the synchronized keyword on an instance method uses 'this' as a monitor ,also using it on a class method (static method) uses the class' Class object (Foo.class).
This way you can synchronize entire methods, and in the same time, synchronize it with a code snippet in another method using the synchronized-block style.
I can't see any functional difference - both synchronize their entire method bodies on (this). How did the person who commented that these are different justify their statement?
They are not quite equivalent in function. Other code could use reflection to see if your method has the synchronized modifier, but there is no way to tell if a method contains a synchronized block without reading its bytecode.
The ability to determine if a method is synchronized occasionally comes in handy. Personally, I've used that flag to avoid redundant locking when doing synchronization in aspect-oriented programming.
MyObject myObjectA;
MyObject myObjectB;
public void someMethod() {
synchronized (this) {
//stuff
}
}
public void someMethodA() {
synchronized (myObjectA) {
//stuff
}
}
public void someMethodB() {
synchronized (myObjectB) {
//stuff
}
}
In this case:
someMethod blocks entire class
someMethodA blocks myObjectA only
someMethodB blocks myObjectB only
someMethodA and someMethodB can be invoked at the same time