This question already has answers here:
Is ExecutorService (specifically ThreadPoolExecutor) thread safe?
(6 answers)
Closed 4 years ago.
I was working on a Java EE app that took in user requests from a UI and then keyed off a lon workflow asynchronously for each of these requests using ExecutorService (SinglethreadExecutor). Now since i was using a SinglethreadExecutor and because there was genuine need for the requests to be served one at a time, i did not feel the need for thread safety.
Is my understanding correct ?
Recently i had asked a question Issue when executing asynchronous tasks using ExecutorService and the solution to this question was that i make my code thread safe.
I'm looking if any shared resources that I'm using in my code is causing the need for this thread safety but would just like to be sure that my understanding of
the scenario is correct.
FYI, I have implemented my ExecutorService in a servlet as mentioned in Running a background Java program in Tomcat
Your requests will be passed to a different thread to be executed. Even if this thread doesn't access shared data structures, the passing of the request to the thread and the returning of the result need to be properly synchronized.
If you use one of the submit or invoke methods which use a Future object for returning the results, you can assume that the appropriate synchronization is performed. The javadoc for ExecutorService says this:
Memory consistency effects: Actions in a thread prior to the submission of a Runnable or Callable task to an ExecutorService happen-before any actions taken by that task, which in turn happen-before the result is retrieved via Future.get().
In short, if the requests / tasks don't use shared data structures and you use the interface methods provided, then you should be OK.
There are two things that you need to consider when you need to make something "thread safe": When does a thread make data visible to anyone else? When does a thread try to read shared data?
Imagine this situation: Thread A gets the request. It works a bit on it. Then it calls a method foo() that gets the request as a parameter. foo() starts a new thread. The thread puts the reference to the request as a private, non-final field.
In hardware, thread A has copied the request into the L1 cache of the CPU core on which it runs. Since there is no synchronization between the two threads, A has no idea that some other thread might want to read the modified request, so it never flushes the cache (or it does it too late).
This means that thread B will get a stale request object. It won't see any changes made by thread A. As you can imagine, this usually works: If A doesn't change the request, B works. It breaks as soon as you change the code of A and you have a "but it worked yesterday!" situation.
To fix this, you must tell A to flush its caches even if the current version of your code works without it. There are several ways to do it; Stephen C described one. Two other ways:
You can synchronize foo() - A thread must flush when it enters a synchronized block.
Make the request a final field of B - Object graphs referenced via final fields must be completely flushed at the time the type construction has completed (where type == the class which contains the final field).
Related
During a job meeting.I have heard that Thread Local is absolutely an anti pattern because new Application servers uses new Thread technologies called new IO.In fact,they told me that the problem with ThreadLocal is that a complete thread must wait for the database query to return a response and that's absolutely a waste of resources(memory as well as CPU).
New developed Thread strategy uses a pool of threads so when a thread is not needed any more it will return to pool.What i have heard is that this new Technology is implemented in new AS such us Jboss,Websphere...(i'm not sure).
Can i use it locally with Apache tomcat for example?(if it's possible documentation on that fact)
ThreadLocal is a side character in your story. What you have heard about is asynchronous request processing, which is helped, among other things, by the NIO library.
In this programming paradigm, you don't get a simple method like
Response processRequest(Request req)
Instead you get
void requestReceived(Request req, Response resp)
and within this method you will usually just start the processing by preparing the back-end request and calling its method which will look like
execute(Query q, ResultCallback cb)
and the framework will call your ResultCallback's method resultReady(Result res) which will contain the query result.
The main point here is that the method requestReceived will return immediately, and will not occupy the thread while the back-end request is being processed at the back-end subsystem.
BTW another name for this style of programming is continuation-passing style or CPS. It is because when you call a function, you don't wait for its return value, but rather pass a callback into it which will be called with the function's result, and which implements the continuation of the total request processing.
How ThreadLocal fits into this
If you have followed what I have said above, it should already be clear to you that in this style of request processing, ThreadLocals are a useless concept because the request processing freely jumps from thread to thread, and in a way which is completely outside of your control.
ThreadLocal has basically nothing to do with databases or ThreadPools/ExecutorServices. ThreadLocal just means that the value stored in it is just visible to the Thread how set it. This doesn't cause any blocking. You must confuse some things there.
ThreadLocal: Stores variable per Thread.
"new IO": They most likely meant the java.nio package. It about reading/writing data without blocking.
Threadpools/Executorservice: Bunch of Threads where you can submit Runnables to. You can use ExecutorServices in any Java application, because they are part of the standard library.
For accessing the database you normally use a dedicated system like C3P0, which manages Threads and database connections
I think that i misunderstand the subject.
Well,i will explain in detail what i have heard.
When using ThreadLocal.If we have for example a query to DataBase or JMS call .The thread must be alive for the response to return (suppose that takes 15 minute for example).The thread will be in a waiting situation waiting for Db to return response.so it's a waste for CPU as well as memory.
New Thread management technology uses a pool of threads.In fact during the waiting time.The thread will be used to server another client.
That's what i have heard.
To Marko Topolnik:What you have exposed is asynchronous calls and it does nothing to do with Threads.
ThreadLocals, thread pools, and new IO can cooperate quite well. All you need is to define thread factory when creating a threadpool so that each new thread would get correct threadlocal value at the moment of creation. This value, for example, can keep a reference to java.nio.channels.Selector singleton. Another thread local variable can hold reference to the thread pool itself, so submitting new tasks to the thread pool can be simplified.
Asynchronous framework https://github.com/rfqu/df4j uses thread locals intensively this way.
Question:
A) Write a thread safe class with methods doA(), doB(), doC(). Each of these methods must report the method name, time of invocation, and calling thread name.
B) Write a multi threaded driver that spawns 4 threads, and each thread must call every method – doA(), doB(), doC() – 10 times
I am assuming that it means doA(), doB(), doC() must be safe. But none of them mutate the shared state within the object, they just read object state such as method name, thread name and running time. So, do I need synchronize each method? For the counter within each thread, it is not shared.
I am a little confused here, which of state of the object needs protection?
Edit:
Do we need a mechanism to assure the running sequence of doA(), doB(), doC()? I dont think so.
From the sounds of it, your object will have no mutable state at all. Objects without mutable state are usually (not always, but usually) thread-safe without any additional locking. Of course, if there's additional requirements that do imply mutable state, the answer would be different.
How are you reporting the information? If it's to a console or any other resource that's independent of thread, there's your shared "state". Sort of. Some mechanisms for writing to a console will buffer lines, so you may not have problems, but over multiple lines you'll have to make sure that two don't write to it at the same time. For example, if I were to print:
Thread: A
Method: doA
Running Time: 4.6s
Then I'd want to make sure another thread doesn't start half-way through. Otherwise you may end up with something like this:
Thread: A
Thread: B
Method: doB
Running Time: 4.6s
Method: doA
Running Time: 3.2s
Not so helpful.
So I have a long running process that I want to encapsulate as a Runnable and dispatch it in a thread. To be more specific, I have a POST web service that creates a file in the file system but the creation of the file can take a very long time.
In the resource method of my web service, I want to be able to dispatch a thread to do the file creation and return the status 200. I don't think I can just do Thread.join because this would mean that the current thread would have to wait for the file creation thread to finish. Instead, I want to join the file creation thread to the main thread. Question is, how do I get the main thread in java?
I am not sure whether I get you right. Here is what I understood:
You want to preform a possibly long running operation (file creation)
you do not want you service method to block while that task is exectued
you want the task executed in a thread that exists outside the boundary/lifetime of the single request.
Am I right so far?
If sou really recommend you look into the newer concepts in java.util.concurrent. The concepts described there should give you enogh information tackkle this
Basic credo: Don't think in threads, think in tasks.
General Book recommendation: Java Concurrency in Practice by Brian Goetz
You will need to process the request asynchronously. A separate thread will be created for doing the heavy work and the request receiving thread will be free to process other requests. Please checkout following articles.
Asynchronous processing in Servlet 3.0
Asynchronous support in Servlet 3.0 spec
Asynchronous Support in Servlet 3.0
When you spawn the file-creation thread, you need to pass it some kind of reference to the parent thread, so it can communicate back (i.e. you provide something to enable a callback).
This could be the actual Thread object (obtained using Thread.currentThread, as someone said in a comment) or some other object that you use to signal when the file-creation thread is done.
This is homework.
I do not want the solution, just a small number of links or ideas.
Simply speaking what I want to do is,
Simple example :
public class Example
{
public void method()
{
int x = doThat();
//Call other methods which do not depend on x
return;
}
}
doThat() is a method that is known to be time consuming, which results in my program blocking until results are back. And I want to use different methods of this Object, but program is frozen until doThat() is finished. Those different methods do not necesserely have to be invoked from the method() used in this example, but maybe from outside the object.
I thought about using threads but if I have a huge number of objects (1000+) this probably wont be very efficient (correct me if I am wrong please). I guess if I use threads I have to use one thread per object ?
Is there any other way besides threads that can make the invoking object not block when calling doThat(); ? If threading is the only way, could you provide a link ?
Knowing questions like that get downvoted I will accept any downvotes. But please just a link would be more than great.
Thanks in advance. I hope question is inline with the rules.
I'd also use threads for this, but I simply wanted to add that it would probably be interesting to look at java.util.concurrent.Executors (to create thread pools as you have a number of objects) and the java.util.concurrent.Future and java.util.concurrent.Callable classes which will allow you to launch threads that can return a value.
Take a look at the concurrency tutorial for more info.
I recommend you to create a class that implements Runnable, whose run method does what doThat() does in your sample. Then you can invoke it in a separate Thread in a simple way. Java's Thread class does have a constructor that takes a runnable. Use the run and join methods.
Cheers
Matthias
Of course threads are the only solution to handle some jobs in backgrounds, but
you are not forced to use a thread just for a single operation to be performed.
You can use only one thread that maintains a queue of operations to be performed, in a way that every call to the method doThat adds a new entry into the queue.
Maybe some design patterns like "Strategy" can help you to generalize the concept of operation to be performed, in order to store "operation objects" into the thread's queue.
You want to perform several things concurrently, so using threads is indeed the way to go. The Java tutorial concurrency lesson will probably help you.
1000 concurrent threads will impose a heavy memory load, because a certain amount of stack memory is allocated for each thread (2 MB?). If, however, you can somehow make sure there will be only one Thread running at a time, you still can take the thread per object approach. This would require you to manage that doThat() is only called, if the thread produced by a former invocation on another object has already finished.
If you cannot ensure that easily, the other approach would be to construct one worker thread which reads from a double ended queue which object to work on. The doThat() method would then just add this to the end of the queue, from which the worker thread will later extract it. You have to properly synchronize when accessing any data structure from concurrent threads. And the main thread should somehow notify the worker thread of the condition, that it will not add any more objects to the queue, so the worker thread can cleanly terminate.
Assuming that I have the following code:
final Catalog catalog = createCatalog();
for (int i = 0; i< 100; i++{
new Thread(new CatalogWorker(catalog)).start();
}
"Catalog" is an object structure, and the method createCatalog() and the "Catalog" object structure has not been written with concurrency in mind. There are several non-final, non-volatile references within the product catalog, there may even be mutable state (but that's going to have to be handled)
The way I understand the memory model, this code is not thread-safe. Is there any simple way to make it safe ? (The generalized version of this problem is really about single-threaded construction of shared structures that are created before the threads explode into action)
No, there's no simple way to make it safe. Concurrent use of mutable data types is always tricky. In some situations, making each operation on Catalog synchronized (preferably on a privately-held lock) may work, but usually you'll find that a thread actually wants to perform multiple operations without risking any other threads messing around with things.
Just synchronizing every access to variables should be enough to make the Java memory model problem less relevant - you would always see the most recent values, for example - but the bigger problem itself is still significant.
Any immutable state in Catalog should be fine already: there's a "happens-before" between the construction of the Catalog and the new thread being started. From section 17.4.5 of the spec:
A call to start() on a thread
happens-before any actions in the
started thread.
(And the construction finishing happens before the call to start(), so the construction happens before any actions in the started thread.)
You need to synchronize every method that changes the state of Catalog to make it thread-safe.
public synchronized <return type> method(<parameter list>){
...
}
Assuming you handle the "non-final, non-volatile references [and] mutable state" (presumably by not actually mutating anything while these threads are running) then I believe this is thread-safe. From the JSR-133 FAQ:
When one action happens before
another, the first is guaranteed to be
ordered before and visible to the
second. The rules of this ordering are
as follows:
Each action in a thread happens before every action in that thread
that comes later in the program's
order.
An unlock on a monitor happens before every subsequent lock on that
same monitor.
A write to a volatile field happens before every subsequent read
of that same volatile.
A call to start() on a thread happens before any actions in the
started thread.
All actions in a thread happen before any other thread successfully
returns from a join() on that thread.
Since the threads are started after the call to createCatalog, the result of createCatalog should be visible to those threads without any problems. It's only changes to the Catalog objects that occur after start() is called on the thread that would cause trouble.