I have a static method with the following signature:
public static List<ResultObjects> processRequest(RequestObject req){
// process the request object and return the results.
}
What happens when there are multiple calls made to the above method concurrently? Will the requests be handled concurrently or one after the other?
Answering exactly your question:
Method will be executed concurrently (multiple times in the same time if you have several threads).
Requests will be handled concurrently.
You need to add the synchronized modifier if you are working with objects that require concurrent access.
All your calls to the method will be executed concurrently... but:
You may have concurrency issue (and being in non thread-safe situation) as soon as the code of your static method modify static variables. And in this case, you can declare your method as synchronized
If your method only use local variables you won't have concurrency issues.
If you need to avoid concurrent execution, you need to explicitly synchronize. The fact that the method is static has nothing to do with it. If you declare the method itself to be synchronized, then the synchronization will be on the class object. Otherwise you will need to synchronize on some static object (since this doesn't exist for static methods).
I see a lot of answers but none really pointing out the reason.
So this can be thought like this,
Whenever a thread is created, it is created with its own stack (I guess the size of the stack at the time of creation is ~2MB). So any execution that happens actually happens within the context of this thread stack.
Any variable that is created lives in the heap but it's reference lives in the stack with the exceptions being static variables which do not live in the thread stack.
Any function call you make is actually pushed onto the thread stack, be it static or non-static. Since the complete method was pushed onto the stack, any variable creation that takes place lives within the stack (again exceptions being static variables) and only accessible to one thread.
So all the methods are thread safe until they change the state of some static variable.
You can check it yourself:
public class ConcurrentStatic {
public static void main(String[] args) {
for (String name: new String[] {"Foo", "Bar", "Baz"}) {
new Thread(getRunnable(name)).start();
}
}
public static Runnable getRunnable(final String name) {
return new Runnable() {
public void run() {
longTask(name);
}
};
}
public static void longTask(String label) {
System.out.println(label + ": start");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(label + ": end");
}
}
all method invocations from separate threads in java are concurrent by default.
Related
I often see the following pattern. One thread will initialize the client in init() method in synchronized block. All the other threads, also called init() method before they start to use the other class methods.
Client value is not changed after initialization. They dont set the client value as volatile.
My question is that if this is correct to do? Do all of the threads that create client, and call init() method , will after init method finished see the correct initilized value that was initialized byt the first thread that called init() method?
public class DB {
private static Object lock = new Object();
private static Client client;
public init() {
synchronized (lock) {
if (client != null) {
return;
}
client = new Client();
}
}
public insert(Object data) {
client.insert(data); // is this ok to access the client without volatile or synchronized?
}
}
The rationale behind that pattern is that they think that because they read the client under synchronized block in init() method, the client will be set to the correct initialized value, and because the client is never changed, they can use it without volatile or synchronized after. IS this correct assumption?
You can see this pattern for example here: https://github.com/brianfrankcooper/YCSB/blob/cd1589ce6f5abf96e17aa8ab80c78a4348fdf29a/mongodb/src/main/java/site/ycsb/db/MongoDbClient.java where they initialized the database in init method and used it without synchronization after.
It is only safe to do this if you are guaranteed to have called init() before calling insert(data).
There is a happens-before edge created by the synchronized block: the end of the synchronized block happens before the next invocation of the same block.
This means that if a thread has invoked init(), then either:
client was previously uninitialized, so it is initialized on this call.
client was previously initialized, and the write to client is has happened before the current thread enters the synchronized block.
No further synchronization is then necessary, at least with respect to client.
However, if a thread doesn't call init(), then there are no guarantees as to whether client is initialized; and no guarantee as to whether the client initialized by another thread (one that did call init()) will be visible to the current thread (the one that didn't call init()).
Relying on clients to call init() first is brittle. It would be much better either to use an eagerly-initialized field:
public class DB {
private static final Client client = new Client();
public insert(Object data) {
client.insert(data); // Guaranteed to be initialized once class loading is complete.
}
}
or, if you must do it lazily, use a lazy holder:
public class DB {
private static class Holder {
private static final Client client = new Client();
}
public insert(Object data) {
Holder.client.insert(data); // Holder.client is initialized on first access.
}
}
Or, of course, chuck in a call to init() inside the insert method:
public insert(Object data) {
init();
client.insert(data);
}
The disadvantage of the latter approach is that all threads must synchronize. In the other two approaches, there is no contention after the first invocation.
It looks like the rationale behind this type of pattern is to ensure that you can only have one instance of Client in the application. Multiple invocations (parallel/sequential) of init() method on different/same DB objects will not allow creating a new Client if it is already created and synchronized block is just to ensure that client object will be created only once if multiple threads called init() parallelly.
But it has nothing to do with safe call of insert() method on client object and that totally depends on the implementation of the insert() method that may be thread-safe or may not be.
I am using java.
I have an instance a of class A which has a public method foo() running and 2 other threads - threadB and threadC, all running at the same time.
here's class A
public class A {
int val = 0
public void foo(int incValue) {
a += incValue;
}
public static void main (String arg[]) {
MyThread a = new MyThread(this);
new Thread(a).start();
MyThread b = new MyThread(this);
new Thread(b).start();
}
}
here's the thread definition for threadB and threadC:
public class MyThread implements Runnable {
A main = null;
public MyThread(A main) {
this.main = main;
}
public callFoo(int incValue) {
main.foo(incValue);
}
#Override
public void run() {
//valToInc can be a value from a GUI form.
callFoo(valToInc);
}
}
If in threadB invokes callFoo(1) and threadC invokes callFoo(3) at the same time, then:
- Which thread will be able to call the method first?
- What is the result of the val in main class after both executions?
- Will the execution of the method for each thread happen concurrently or one after another?
There is absolutely no difference in how the JVM will invoke two methods "in parallel".
In other words: if you want to know what happens when a method is called, you can look here.
When a method is called "twice" in parallel, then that whole thing ... just happens twice!
Things become interesting when that method is making updates on that class, or in other objects! (like changing a field of your object, or appending a value to a list, ... )
You see, the real complexity of multi-threading is not about running some code in parallel. The real issue is what happens to "shared data".
If you find my answer to general; sorry - that is probably the best you can expect for such a generic question.
If [] threadB invokes callFoo(1) and threadC invokes callFoo(3) at the same time, then: - Which thread will be able to call the method first?
Threads run independently of each other. If there is no synchronization (there's none in your example), then any number of threads can be in calls to the same method at the same time.
Whenever a thread calls a method, it creates an activation record to hold all of the local variables and parameters of that method, and when several threads call the same method at the same time, each thread gets its own activation record. The threads can neither communicate with one another through the args and locals, nor can they interfere with one another's use of the args and locals.
They can, of course communicate and interfere with each other through any shared objects, including objects that may be referenced by the args or the locals.
I have a utility class as follows:
public class MetaUtility {
private static final SparseArray<MetaInfo> metaInfo = new SparseArray<>();
public static void flush() {
metaInfo.clear();
}
public static void addMeta(int key, MetaInfo info) {
if(info == null) {
throw new NullPointerException();
}
metaInfo.append(key, info);
}
public static MetaInfo getMeta(int key) {
return metaInfo.get(key);
}
}
This class is very simple and I wanted to have a "central" container to be used across classes/activities.
The issue is threading.
Right now it is populated (i.e the addMeta is called) only in 1 place in the code (not in the UI thread) and that is not going to change.
The getter is accessed by UI thread and in some cases by background threads.
Carefully reviewing the code I don't think that I would end up with the case that the background thread would add elements to the sparse array while some other thread would try to access it.
But this is very tricky for someone to know unless he knew the code very well.
My question is, how could I design my class so that I can safely use it from all threads including UI thread?
I can't just add a synchronized or make it block because that would block the UI thread. What can I do?
You should just synchronize on your object, because what your class is right now is just a wrapper class around a SparseArray. If there are thread level blocking issues, they would be from misuse of this object (well, I guess class considering it only exposes public static methods) in some other part of your project.
First shoot can be with synchronized.
#Jim What about the thread scheduling latency?
Android scheduler is based on Linux and it is known as a completely fair scheduler (CFS). It is "fair" in the sense that it tries to balance the execution of tasks not only based on the priority of the thread but also by tracking the amount of execution time that has been given to a thread.
If you'll see "Skipped xx frames! The application may be doing too much work on its main thread", then need some optimisations.
If you have uncontended lock you should not be afraid of using synchronized. In this case lock should be thin, which means that it would not pass blocked thread to OS scheduler, but would try to acquire lock again a few instructions after. But if you still would want to write non-blocking implementation, then you could use AtomicReference for holding the SparseArray<MetaInfo> array and update it with CAS.
The code might be smth like this:
static AtomicReference<SparseArray<MetaInfo>> atomicReference = new AtomicReference<>();
public static void flush() {
atomicReference.set(new SparseArray<MetaInfo>);
}
public static void addMeta(int key, MetaInfo info) {
if(info == null) {
throw new NullPointerException();
}
do {
SparseArray<MetaInfo> current = atomicReference.get();
SparseArray<MetaInfo> newArray = new SparseArray<MetaInfo>(current);
// plus add a new info
} while (!atomicReference.compareAndSet(current, newArray));
}
public static MetaInfo getMeta(int key) {
return atomicReference.get().get(key);
}
I'm doing a short course about Threads in Java, in one of my homeworks they asked me: ¿Why you don't should be synchronize the run method? show an example.
I searched about it, and that i think is use synchronized for a run method is not useful, at least commonly. Because the people don't call the run method manually, so the synchronized effect isn't visible creating multiple instances of a object with synchronized run.
So, i would like know if exist another reason or if i'm wrong.
Syncrhonizing the run() method of a Runnable is completely pointless unless you want to share the Runnable among multiple threads and you want to serialize the execution of those threads. Which is basically a contradiction in terms.
If the run method of a Runnable were synchronized, then either
a) you have many runnables (in which case, no need to synchronise, as each one is called on a different object), or else
b) you have one runnable being called in many threads - but then they clearly won't run in parallel -- thus defeating the purpose of having multiple threads!
You may synchronize on run method, nothing wrong with it. I think the reasons behind this advice should be explained to you by the instructor of course.
We need synchronization when there are shared resources (between threads).
Synchronizing on a method is same as synchronizing on this which will block other method calls.
As a counter example, a poor man's Future implementation;
public class SynchronizedRun {
static abstract class Future<T> implements Runnable{
private T value;
public synchronized T getValue(){
return value;
}
protected void setValue(T val){
value = val;
}
}
public static void main(String[] args) {
Future<Integer> longRunningJob = new Future<Integer> (){
#Override
synchronized public void run() {
try {
Thread.sleep(5000);
setValue(42);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread(longRunningJob).start();
System.out.println("getting results");
System.out.println("result = " + longRunningJob.getValue());
}
}
I have a class that has the object "Card". This class keeps checking to see if the object is not null anymore. Only one other thread can update this object. Should I just do it like the code below? Use volatile?Syncronized? lock (which I dont know how to use really)? What do you recommend as easiest solution?
Class A{
public Card myCard = null;
public void keepCheck(){
while(myCard == null){
Thread.sleep(100)
}
//value updated
callAnotherMethod();
}
Another thread has following:
public void run(){
a.myCard = new Card(5);
}
What do you suggest?
You should use a proper wait event (see the Guarded Block tutorial), otherwise you run the risk of the "watching" thread seeing the reference before it sees completely initialized member fields of the Card. Also wait() will allow the thread to sleep instead of sucking up CPU in a tight while loop.
For example:
Class A {
private final Object cardMonitor = new Object();
private volatile Card myCard;
public void keepCheck () {
synchronized (cardMonitor) {
while (myCard == null) {
try {
cardMonitor.wait();
} catch (InterruptedException x) {
// either abort or ignore, your choice
}
}
}
callAnotherMethod();
}
public void run () {
synchronized (cardMonitor) {
myCard = new Card(5);
cardMonitor.notifyAll();
}
}
}
I made myCard private in the above example. I do recommend avoiding lots of public fields in a case like this, as the code could end up getting messy fast.
Also note that you do not need cardMonitor -- you could use the A itself, but having a separate monitor object lets you have finer control over synchronization.
Beware, with the above implementation, if run() is called while callAnotherMethod() is executing, it will change myCard which may break callAnotherMethod() (which you do not show). Moving callAnotherMethod() inside the synchronized block is one possible solution, but you have to decide what the appropriate strategy is there given your requirements.
The variable needs to be volatile when modifying from a different thread if you intend to poll for it, but a better solution is to use wait()/notify() or even a Semaphore to keep your other thread sleeping until myCard variable is initialized.
Looks like you have a classic producer/consumer case.
You can handle this case using wait()/notify() methods. See here for an example: How to use wait and notify in Java?
Or here, for more examples: http://www.programcreek.com/2009/02/notify-and-wait-example/