Thread safety between subsequent calls of an Executors.newSingleThreadExecutor - java

I have a question regarding using a single threaded executor. Since it reuses the same thread, does that means that If I modify an object state in one submit call, can I assume that another modification of that object state in subsequent calls of submit are thread safe? Let me give a toy example...
public class Main {
public static void main(String[] args) throws Exception {
final A a = new Main().new A();
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Integer> callable = new Callable<Integer>() {
#Override
public Integer call() throws Exception {
return a.modifyState();
}
};
/* first call */
Future<Integer> result = executor.submit(callable);
result.get();
/* second call */
result = executor.submit(callable);
int fin = result.get();
System.out.println(fin);
executor.shutdown();
}
class A {
private int state;
public int modifyState() {
return ++state;
}
public int getState() {
return state;
}
}
}
So I am sharing object A. I submit a callable and modify it's state first ( see /* first call / ). I then do another submit call, modify again A state. (/ second call */).Now my big question
Is it safe to say that, since it's the same thread, the second submit call will see A.state as being 1? Or could it see it as being 0 in some cases too?
So basically I am asking if it's safe to modify variables that are not marked as volatile/accessed from synchronized blocks in subsequent submit calls of a single thread executor?, since it reuses the same thread
What exactly does thread reusing means regarding executors? Is it really the same thread at OS level in the case of an single thread executor?

It actually doesn't matter that it is single threaded. The javadoc of ExecutorService states:
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().

Executors.newSingleThreadExecutor() gives you thread safety by guaranteeing only one thread running at a time. It also gives you grantee about visibility which means any state change during one thread execution will be visible to next thread execution.

Related

JavaFX Task Callable

I was developing a JavaFX app and I was supplying the JavaFX tasks in an ExecutorService submit method. Also I was trying to get the return value of the Task in the return value of the submit in a Future object. Then I discovered that ExecutorService only returns value when you submit a Callable object, and JavaFX Tasks are runnables despite having a call method. so is there any workaround for this problem?
I tried and solved my problem this way but I'm open to suggestions when I don't want to write my own class.
My main method:
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Semaphore semaphore = new Semaphore(1);
List<Integer> list = IntStream.range(0,100).boxed().collect(Collectors.toList());
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()){
List<Integer> sendingList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
sendingList.add(iterator.next());
}
System.out.println("SUBMITTING");
Future<Integer> future = executorService.submit((Callable<Integer>) new TestCallable(sendingList,semaphore));
System.out.println(future.get());
semaphore.acquire();
}
executorService.shutdown();
System.out.println("COMPLETED");
}
My TestCallable class:
class TestCallable extends Task<Integer> implements Callable<Integer> {
private Random random = new Random();
private List<Integer> list;
private Semaphore semaphore;
TestCallable(List<Integer> list, Semaphore semaphore) {
this.list = list;
this.semaphore = semaphore;
}
#Override
public Integer call(){
System.out.println("SENDING");
System.out.println(list);
try {
Thread.sleep(1000+random.nextInt(500));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("RECEIVED");
semaphore.release();
return list.size();
}
}
Task extends java.util.concurrent.FutureTask which in turn implements the Future interface. This means you can use a Task just like a Future.
Executor executor = ...;
Task<?> task = ...;
executor.execute(task);
task.get(); // Future method
This will cause the thread calling get() to wait until completion. However, a Task's purpose is to communicate the progress of a background process with the JavaFX Application Thread. It's close relationship to the GUI means you will most likely be launching a Task from the FX thread. This will lead to get() being called on the FX thread which is not what you want as it will freeze the GUI until get() returns; you might as well have just called Task.run directly.
Instead, you should be using the asynchronous functionality provided by Task. If you want to retrieve the value when the Task completes successfully you can use the onSucceeded property or listen to the value/state property. There's also ways to listen for failure/cancellation.
Executor executor = ...;
Task<?> task = ...;
task.setOnSucceeded(event -> handleResult(task.getValue()));
task.setOnFailed(event -> handleException(task.getException()));
executor.execute(task);
If you don't need the functionality provided by Task then it would probably be best to simply use Runnable or Callable directly.
It's not very clear what you want to do here.
Firstly, your Semaphore does nothing because you used Executors.newSingleThreadExecutor(), which already guarantees that only one task can run at any point in time.
Secondly, like what #Slaw mentioned, you are potentially blocking on JavaFX Application thread, depending on your actual implementation (your example isn't really a JavaFX application).
Next, ExecutorService has 2 main overloads for submit().
The first overload takes in a Callable. This overload allows you to retrieve the value returned by the Callable (by calling get() on the returned Future), because Callable refers to something that is can be called - it can return value.
The second overload takes in a Runnable. Since Task implements Future RunnableFuture interface, and Future RunnableFuture interface extends Runnable interface, passing in a Task would be equivalent to calling this overload. This overload does not expect a result to be returned, because Runnable is something that you run without a result. Calling get() on the Future returned by this overload will block until the task finishes, and null will be returned. If you need to retrieve the value returned by the Task, you need to call get() of the Task, not the Future returned by ExecutorService.submit().
Edit based on OP's comments
Firstly, since the calling method is already running in a background thread, and all tasks are expected to run sequentially (instead of parallelly), then you should just run them without all these additional ExecutorService and Task, unless there is another reason why this has to be done.
Secondly, a List object is nothing but an object doing referencing. What could have really affected performance is that you are copying the reference of the elements to the new list. You could have used List.subList()if the indices are known, as the returned list would use the same backing array as the original list, so there isn't an additional O(n) operation for copying.

When is runnable object garbage collected in ExecutorService?

I have a runnable object A which exchanges heart beat signals with a server on instantiation. I submit n such objects to a executor service with fixed thread pool size of n. When the run method encounters exception it would return. For a given case, all my threads encounter exception and return, but the object created remains alive and keeps on exchanging the heart beat signals. How do I mark such objects up for garbage collection so that they would stop the heart beat signals exchange?
class A implements Runnable {
public void run(){
try{
\\throws error
} catch(Exception e){
\\returns
}
}
public static void main(){
ExecutorService executor = Executors.newFixedThreadPool(n)
for(i = 1 to n){
A a = new A()
executor.submit(a)
}
}
}
Should I put a awaitTermination call at the end of my main and do a return?
Edit:
Putting the question other way, one way to terminate the executorservice after all the threads return would be to call shutdown() after the for loop and call awaitTermination with Integer.MAX long seconds which is roughly 70 years ( which is a time constraint I am reluctant to impose). Is there any other alternative?
one way to terminate the executorservice after all the threads return would be to call shutdown() after the for loop and call awaitTermination with Integer.MAX long seconds which is roughly 70 years
as the doc says the awaitTermination method will block util:
all tasks have completed execution after a shutdown request
or the timeout occurs,
or the current thread is interrupted, whichever happens first
So it will game over as soon as one of the three event turn up, rather than have to wait 70 years.
calling shutdown() on pool means the pool will no longer accept any new task for execution, but the current ones will run without interruption.
calling awaitTermination(timeout) holds the calling thread till the pool is finished, but if timeout is reached, then current thread throws execption, but it will not affect the tasks in pool.
If your runnable throws uncought exception when is run by thread pool, then this runnable is no longer in run state - thread pool doesn't hold any reference to such object usually.
If you use FixedThreadPool, then this pool will create as many threads as you wish, and will not stop any of them until you call shutdown() on this pool.
If you don't have reference to the runnable object that throwed the exception it behaves as regular unreferenced Object to be Garbage Collected.
if you call shutdown() and then awaitTermination() on thread pool, and your program doesn't stop anyway, that means not all instances of your runnable have thrown an exception, and some are still running thus blocking the pool from complete shutdown.
In java you can't kill or stop running thread just like that (you can only kill entire JVM using eg. System.exit(0), but not just choosen thread), if you need such functionality you need to program the body of the runnable in a way that lets you communicate somehow with it, ie. using some "volatile boolean" variable, and that it will respond to change in the value of this variable - it means that you need to add "if checks" for the value of this variable in the body of the run() method that will return when it should.
The tasks themselves are eligible for garbage collecting as soon as their execution is complete. If and when they are actually collected depends on the garbage collector.
Example code:
public class Main implements Runnable {
#Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalize");
}
#Override
public void run() {
try {
throw new Exception("Error");
} catch (Exception e) {
//returns
}
}
public static void main(String args[]) {
int n = 8;
ExecutorService executor = Executors.newFixedThreadPool(n);
for (int i = 0 ; i < n; ++i) {
Main a = new Main();
executor.submit(a);
}
System.gc();
System.out.println("end");
}
}

Can a non-volatile variable that is delayed assigned to by a method of the class not be read by another thread?

Consider the following code:
import java.util.concurrent.Callable;
final public class DelayedSet {
String Val = "Uninitialized";
public Callable<String> Makegetter(String val) {
this.Val = val;
return new Callable<String>() {
public String call() {
return DelayedSet.this.Val;
}
};
}
}
class Main {
public static void main(String[] args) {
DelayedSet x = new DelayedSet();
Callable<String> Foogetter = x.Makegetter("Initialized");
// Version 1
try {
System.out.println(Foogetter.call());
}
catch (Exception e) {
}
}
}
After running Main, "Initialized" is printed.
Now consider Variant A, where Foogetter is passed to a new Thread. Will then Foogetter also return "Initialized" or is it possible, due to an out-of-date cache condition, for Foogetter to return "Uninitialized"?
Also consider Variant B, where we have three threads, T1, T2, and T3. T1, via futures, submits a Callable to T2, where T2 creates DelayedSet, calls Makegetter, and returns "Foogetter" (in quotes since its technically anonymous) via the future back to T1. T1 then takes this result (the "Foogetter"), and submits another callable, this time to T3, where T3 calls "Foogetter". For both variants, is it guaranteed that "Initialized" will be returned or can "Uninitialized" ever be returned?
To summarize in psuedocode:
T1:
futureT2 = executorService.submit(new Callable {
...
call() {
// Runs in T2
Foo = new DelayedSet;
return Foo.Makegetter("Initialized");
} ...
futureT3 = executorService.submit(futureT2.get());
print(futureT3.get());
Coming from this question, I get the impression that one would need to rely on synchronization events to piggy back on, such as a volatile or synchronized block. However, I'm trying to determine the special case to not require volatiles (even via piggybacking), but due to happen-before semantics of thread creation and joining, will not incur any out-of-date cache conditions.
Can anyone clarify what the memory model with regard to threading is, in order to answer the question?
For Variant A, I'm going to assume something like
new Thread(() -> {
try {
System.out.println(Foogetter.call());
} catch (Exception e) {
}
}).start();
In this case, the JLS has us covered
A call to start() on a thread happens-before any actions in the started thread.
The
this.Val = val;
happened within the Makegetter invocation which happens-before the invocation of Thread#start() which then happens before the invocation of call within the started thread. The value returned will always have to be "Initialized".
In Variant B, the first thing to note is the memory consistency effect of Future
Actions taken by the asynchronous computation happen-before actions
following the corresponding Future.get() in another thread.
By the time futureT2.get() returns in T1, the call invocation in T2 has happened(-before) and the invocation of MakeGetter has already set the value of DelayedSet.Val. This change is visible to T1 which gets the Callable and to T3 which returns this updated value and to T1 again which retrieves it with futureT3.get().

Control Multithreading in Java

I have one "Runnable" threads which is initiating few "Callable" threads and I want to display results when all above threads has finished their jobs.
What is the best way to do it?
My code is as follows
Connector.java (Starting Runnable Thread)
public class Connector {
private static void anyFileConnector() {
// Starting searching Thread
ExecutorService executor = Executors.newFixedThreadPool(100);
executor.submit(traverse, executor);
//HERE I WANT MY ALL SEARCH RESULTS/OUTPUT : CURRENTLY IT IS STARTING OTHER THREADS AND NOT SHOWING ME ANY RESULTS BECAUSE NONE OF THEM WAS FINISHED.(IN CONSOLE, I WAS ABLE TO SEE RESULTS FROM ALL THE THREADS
setSearchResult(traverse.getResult());
executor.shutdown();
}
}
Traverse.java (Runnable Thread)
I am using ExecutorCompletionService to handle it...but it didn't create any difference.
:(
public class Traverse implements Runnable {
public void run() {
ExecutorService executor = Executors.newFixedThreadPool(100);
ExecutorCompletionService<List<ResultBean>> taskCompletionService =
new ExecutorCompletionService<List<ResultBean>>(executor);
try (DirectoryStream<Path> stream = Files
.newDirectoryStream(dir)) {
Search newSearch = new Search();
taskCompletionService.submit(newSearch);
}
list.addAll(taskCompletionService.take().get());
}
}
Search.java (Callable Thread)
public class Search implements Callable<List<ResultBean>> {
public List<ResultBean> call() {
synchronized (Search.class) {
// It will return results
return this.search();
}
}
}
Go for CyclicBarrier and you will be able to achieve this.
A cyclic barrier will perform a task as soon as all the threads are done with their work, this is where you can print the en result.
Check this lik for working of CyclicBarrier : http://javarevisited.blogspot.com/2012/07/cyclicbarrier-example-java-5-concurrency-tutorial.html
Easy - all the Callables will return Future objects which you can used to wait and get the result by calling Future.get() in a blocking wait way. So your problem is just a for loop waiting for each future on the callables blockingly.
After that, just aggregate the results to return to client.
The submit method of executor service can return a list of Future objects. What you can do for your case is call isDone() method of these Future objects in a while loop.
Whenever, any future task gets completed this method will return true. You can now call get() method on this to get the value returned by this task. In this way you could get hold of all the future task values without having to wait for any particular task to get complete (since your first future task could have the longest completion time)

Java - threads + action

I'm new to Java so I have a simple question that I don't know where to start from -
I need to write a function that accepts an Action, at a multi-threads program , and only the first thread that enter the function do the action, and all the other threads wait for him to finish, and then return from the function without doing anything.
As I said - I don't know where to begin because,
first - there isn't a static var at the function (static like as in c / c++ ) so how do I make it that only the first thread would start the action, and the others do nothing ?
second - for the threads to wait, should I use
public synchronized void lala(Action doThis)
{....}
or should i write something like that inside the function
synchronized (this)
{
...
notify();
}
Thanks !
If you want all threads arriving at a method to wait for the first, then they must synchronize on a common object. It could be the same instance (this) on which the methods are invoked, or it could be any other object (an explicit lock object).
If you want to ensure that the first thread is the only one that will perform the action, then you must store this fact somewhere, for all other threads to read, for they will execute the same instructions.
Going by the previous two points, one could lock on this 'fact' variable to achieve the desired outcome
static final AtomicBoolean flag = new AtomicBoolean(false); // synchronize on this, and also store the fact. It is static so that if this is in a Runnable instance will not appear to reset the fact. Don't use the Boolean wrapper, for the value of the flag might be different in certain cases.
public void lala(Action doThis)
{
synchronized (flag) // synchronize on the flag so that other threads arriving here, will be forced to wait
{
if(!flag.get()) // This condition is true only for the first thread.
{
doX();
flag.set(true); //set the flag so that other threads will not invoke doX.
}
}
...
doCommonWork();
...
}
If you're doing threading in any recent version of Java, you really should be using the java.util.concurrent package instead of using Threads directly.
Here's one way you could do it:
private final ExecutorService executor = Executors.newCachedThreadPool();
private final Map<Runnable, Future<?>> submitted
= new HashMap<Runnable, Future<?>>();
public void executeOnlyOnce(Runnable action) {
Future<?> future = null;
// NOTE: I was tempted to use a ConcurrentHashMap here, but we don't want to
// get into a possible race with two threads both seeing that a value hasn't
// been computed yet and both starting a computation, so the synchronized
// block ensures that no other thread can be submitting the runnable to the
// executor while we are checking the map. If, on the other hand, it's not
// a problem for two threads to both create the same value (that is, this
// behavior is only intended for caching performance, not for correctness),
// then it should be safe to use a ConcurrentHashMap and use its
// putIfAbsent() method instead.
synchronized(submitted) {
future = submitted.get(action);
if(future == null) {
future = executor.submit(action);
submitted.put(action, future);
}
}
future.get(); // ignore return value because the runnable returns void
}
Note that this assumes that your Action class (I'm assuming you don't mean javax.swing.Action, right?) implements Runnable and also has a reasonable implementation of equals() and hashCode(). Otherwise, you may need to use a different Map implementation (for example, IdentityHashMap).
Also, this assumes that you may have multiple different actions that you want to execute only once. If that's not the case, then you can drop the Map entirely and do something like this:
private final ExecutorService executor = Executors.newCachedThreadPool();
private final Object lock = new Object();
private volatile Runnable action;
private volatile Future<?> future = null;
public void executeOnlyOnce(Runnable action) {
synchronized(lock) {
if(this.action == null) {
this.action = action;
this.future = executor.submit(action);
} else if(!this.action.equals(action)) {
throw new IllegalArgumentException("Unexpected action");
}
}
future.get();
}
public synchronized void foo()
{
...
}
is equivalent to
public void foo()
{
synchronized(this)
{
...
}
}
so either of the two options should work. I personally like the synchronized method option.
Synchronizing the whole method can sometimes be overkill if there is only a certain part of the code that deals with shared data (for example, a common variable that each thread is updating).
Best approach for performance is to only use the synchronized keyword just around the shared data. If you synchronized the whole method when it is not entirely necessarily then a lot of threads will be waiting when they can still do work within their own local scope.
When a thread enters the synchronize it acquires a lock (if you use the this object it locks on the object itself), the other will wait till the lock-acquiring thread has exited. You actually don't need a notify statement in this situation as the threads will release the lock when they exit the synchronize statement.

Categories

Resources