Synchronizing Hashmap in Threading - java

I am facing some issues with synchronizing my idMap. This map is being used in two run() methods which are run concurrently. In the 1st run() method i'm simply mapping event id value) to response id (key). in the 2nd run() method I wish to obtain the event id (value) with that same response id (key). However, at times some event id is there and at times they can't be obtained. The program compiles just fine, but i'm no expert at threading and i believe threading is causing this idMap to be out of sync. My question is simply, how can I make idMap work smoothly and obtain the event ids as I intend to?
ConcurrentHashMap<String, String> idMap = new ConcurrentHashMap<String, String>();
ConcurrentHashMap<String, ExecutorService> executors = new ConcurrentHashMap<String, ExecutorService>();
private final class ResponderTask implements Runnable {
private ResponderTask(Event event) {
this.event = event;
}
// 1st run()
public void run() {
idMap.put(response.getId(), event.getId());
}
}//end ResponderTask
private final class QuoteTask implements Runnable {
//constructor
//2nd run()
public void run() {
IdMap.get(response.getId());
}
}//end QuoteTask
public void onResponse(final Response response) {
ExecutorService quoteExecutor = executors.get(response.getId());
if (quoteExecutor == null) {
quoteExecutor = Executors.newSingleThreadExecutor();
executors.put(event.getId(), quoteExecutor);
}
quoteExecutor.execute(new ResponderTask(event));
}

However, at times some event id is there and at times they can't be obtained. The program compiles just fine, but i'm no expert at threading and i believe threading is causing this idMap to be out of sync.
idMap is a ConcurrentHashMap which is properly synchronized and highly used and tested by many folks. If the id is not in the map when you look it up then it has not been put in there. If you explain a bit more about your code we may be able to find your problem.
For example, I don't see where the response object originates from. Is it possible that the ResponseTask is processing a different response then you expect? Is response and event supposed to be the same argument?
My question is simply, how can I make idMap work smoothly and obtain the event ids as I intend to?
It's a little hard to figure out what the proper operation of the program is supposed to be. If you are looking for the other thread to get the event you could use a BlockingQueue. Then your other thread can do a queue.take() which will wait until there is an event to process. But I'm not sure what the goal is here.
One thing that is very strange is the use of a map of ExecutorService. Do you really need multiple of them? I suspect that you really should use a single Executors.newCachedThreadPool(). Maybe, however, you want a single thread working on all requests with the same id in which case your code should work. I assume you are doing something like the following when you want to shutdown you application:
for (ExecutorService executor : executors.values()) {
executor.shutdown();
}

Related

Java - How do I safely stop a thread in a Web App from the GUI?

Is there a way to safely and immediately stop the execution of a Thread in Java? Especially, if the logic inside the run() method of the Runnable implementation executes only a single iteration and does not regularly check for any flag that tells it to stop?
I am building a Web Application, using which a user can translate the contents of an entire document from one language to another.
Assuming the documents are extra-large, and subsequently assuming each translation is going to take a long time (say 20-25 minutes), my application creates a separate Thread for each translation that is initiated by its users. A user can see a list of active translations and decide to stop a particular translation job if he/she wishes so.
This is my Translator.java
public class Translator {
public void translate(File file, String sourceLanguage, String targetLanguage) {
//Translation happens here
//.......
//Translation ends and a new File is created.
}
}
I have created a TranslatorRunnable class which implements the Runnable interface as follows:
public class TranslatorRunnable implements Runnable {
private File document;
private String sourceLanguage;
private String targetLanguage;
public TranslatorRunnable(File document, String sourceLanguage, String targetLanguage) {
this.document = document;
this.sourceLanguage = sourceLanguage;
this.targetLanguage = targetLanguage;
}
public void run() {
// TODO Auto-generated method stub
Translator translator = new Translator();
translator.translate(this.document, this.sourceLanguage, this.targetLanguage);
System.out.println("Translator thread is finished.");
}
}
I'm creating the thread for translating a document from an outer class like this:
TranslatorRunnable tRunnable = new TranslatorRunnable(document, "ENGLISH", "FRENCH");
Thread t = new Thread(tRunnable);
t.start();
Now my problem is how do I stop a translation process (essentially a Thread) when the user clicks on "Stop" in the GUI?
I have read a few posts on StackOverflow as well as on other sites, which tell me to have a volatile boolean flag inside the Runnable implementation, which I should check on regularly from inside the run() method and decide when to stop. See this post
This doesn't work for me as the run() method is just calling the Translator.translate() method, which itself is going to take a long time. I have no option here.
The next thing I read is to use ExecutorService and use its shutDownAll() method. But even here, I'd have to handle InterruptedException somewhere regularly within my code. This, is again out of the option. Referred this documentation of the ExecutorService class.
I know I cannot use Thread.stop() as it is deprecated and may cause issues with objects that are commonly used by all threads.
What options do I have?
Is my requirement really feasible without substantial changes to my design? If yes, please tell me how.
If it is absolutely necessary for me to change the design, could anyone tell me what is the best approach I can take?
Thanks,
Sriram
Is there a way to safely and immediately stop the execution of a Thread in Java?
No. each thread is reponsible to periodically check if it has been interrupted to exit as soon as possible
if (Thread.currentThread().isInterrupted() ) {
// release resources. finish quickly what it was doing
}
if you want a more responsive application, you have to change the logic (for example divide each job in smaller batches) so each thread does this checking more often than every 20-25 minutes
If you are the one that created the Translator class what's stopping you from adding some kind of value inside the function that is checked periodically and if needed stops reading the lines from file something like this
public static List<String> readFile(String filename)
{
List<String> records = new ArrayList<>();
try
{
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line;
while ((line = reader.readLine()) != null)
{
String[] split = line.split("\\s+");
records.addAll(Arrays.asList(split));
if (needsToStop) {
break; //Or throw exception
}
}
reader.close();
return records;
}
catch (Exception e)
{
System.err.format("Exception occurred trying to read '%s'.", filename);
e.printStackTrace();
return null;
}
}

Android - Wait for a UI thread callback without returning from function

I'm investigating making a framework to use a WebView to run arbitrary JavaScript. It works fine.
For programmer convenience I'd like to be able to make a synchronous call invoking a bit of JavaScript, and get the result within a single function (No comments please about code execution speed. Of course it'll be slow).
But the threading model is causing me problems. WebView makes its callbacks to the UI thread - which is nice and programmer-friendly. But it makes trouble for me. I'd like to be able to do this in the UI thread:
String four = X.invokeJavaScriptReturningString("2+2"); // result "4"
where the method is as follows:
public String invokeJavaScriptReturningString( final String javaScript) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
final String[] result = new String[1]; // Kludge - array is assignable from nested class.
ValueCallback<String> callback = new ValueCallback<String>() {
#Override
public void onReceiveValue(String s) {
result[0] = s;
latch.countDown();
}
};
mWebView.evaluateJavascript(javaScript, callback);
latch.await(99, TimeUnit.SECONDS);
return result[0];
}
But of course the callback message gets queued in the UI thread message queue, and the function blocks for 99 seconds then returns null.
Some message-based thread models have a way to work around this; something like:
while (!latch.await(1, TimeUnit.MILLISECONDS) {
// Process any messages in the UI thread Looper queue.
}
But I can't find any way to get at the Android Looper queue.
Any suggestions how to solve this?

JavaFX SwingWorker Equivalent?

Is there a JavaFX equivalent to the Java SwingWorker class?
I am aware of the JavaFX Task but with that you can only publish String messages or a progress. I just want to call a method in the GUI thread like I would have done with the SwingWorker (by publishing messages of an arbitrary type).
Heres is an example of what I mean:
class PrimeNumbersTask extends
SwingWorker<List<Integer>, Integer> {
PrimeNumbersTask(JTextArea textArea, int numbersToFind) {
//initialize
}
#Override
public List<Integer> doInBackground() {
while (! enough && ! isCancelled()) {
number = nextPrimeNumber();
publish(number);
setProgress(100 * numbers.size() / numbersToFind);
}
}
return numbers;
}
#Override
protected void process(List<Integer> chunks) {
for (int number : chunks) {
textArea.append(number + "\n"); // HERE: execute in GUI thread
}
}
}
Solution
Thank you very much for your answers. The solution I was searching for, is to use Platform.runLater(Runnable guiUpdater).
I would rewrite your SwingWorker as follows:
class PrimeNumbersTask extends Task<List<Integer>> {
PrimeNumbersTask(TextArea textArea, int numbersToFind) {
// initialize
}
#Override
protected List<Integer> call() throws Exception {
while (!enough && !isCancelled()) {
number = nextPrimeNumber();
updateMessage(Integer.toString(number));
updateProgress(numbers.size(), numbersToFind);
}
return numbers;
}
}
Usage:
TextArea textArea = new TextArea();
PrimeNumbersTask task = new PrimeNumbersTask(numbersToFind);
task.messageProperty().addListener((w, o, n)->textArea.appendText(n + "\n"));
new Thread(task).start(); // which would actually start task on a new thread
Explanation:
Yes, we do not have a publish() method as the SwingWorker does in JavaFX, but in your case using the updateMessage() is sufficient, as we can register a listener to this property and append a new line every time the message is updated.
If this is not enough, you can always use Platform.runLater() to schedule GUI updates. If you are doing too many GUI updates and the GUI Thread is being slowed down, you can use the following idiom: Throttling javafx gui updates
Apart from the updateMessage method where you can only pass strings, there is the updateValue method where you can pass a whole object, so I believe you can use that in a similar manner. This approach is described in the "A Task Which Returns Partial Results" section of the Task documentation. Another approach is the Platform.runLater() approach mentioned also in other answer.
Note that an important difference between these approaches, is that the first one is coalescing the results, which means that for multiple frequent updateValue calls some may be omitted in order to protect flooding the FX thread.
On the other hand, the Platform.runLater approach will send all the interim results, but due to the danger of flooding the FX thread if you have high frequency updates, some additional effort may be needed to manually avoid it like #eckig suggested in his answer which points to Throttling javafx gui updates
Don't ever use SwingWorker. This piece of code in the SwingWorker.java source should be enough of an argument to not use it:
private static final int MAX_WORKER_THREADS = 10;
Instead get yourself familiar with Executor and the services that come along with it.
It has nothing to do with JavaFX, it's just plain Java. However, your question was related to JavaFX. Here's an example about how to Update UI in JavaFX Application Thread using Platform.runLater().

Multiple threads. Doing similar tasks, but need to see their output

I have a program which I select the amount of threads and it starts it, but I would like to have control of closing each thread one by one after they have started and see there output of each thread as well.
What is the best approach in this case?
These methods allow you to fetch results of all tasks, that were submitted to an executor service. And this shuts it down.
Create a Hashtable that will contain your threads and have the thread name used as the Key in the hashmap. So whenever you want to perform an operation on your thread you can get its reference from the hashtable and do whatever you want with it.
Hashtable<String, Thread> threadTable = new Hashtable<String, Thread>();
Thread t1 = new Thread() {
public void run() {
//Do sttuff
}
}
Thread t2 = new Thread() {
public void run() {
//Do sttuff
}
}
threadTable.put("T1", t1);
threadTable.put("T2", t2);
Of course this the above is just a simple example. If you take a class and make it extends Thread, you can then add methods to suspend and resume the thread as well as printing out its status.

Multi threading with Java Executor

I am stuck with this following problem.
Say, I have a request which has 1000 items, and I would like to utilize Java Executor to resolve this.
Here is the main method
public static void main(String[] args) {
//Assume that I have request object that contain arrayList of names
//and VectorList is container for each request result
ExecutorService threadExecutor = Executors.newFixedThreadPool(3);
Vector<Result> vectorList = new Vector<Result();
for (int i=0;i<request.size();i++) {
threadExecutor.execute(new QueryTask(request.get(i).getNames, vectorList)
}
threadExecutor.shutdown();
response.setResult(vectorList)
}
And here is the QueryTask class
public QueryTask() implements Runnable {
private String names;
private Vector<Result> vectorList;
public QueryTask(String names, Vector<Result> vectorList) {
this.names = names;
this.vectorList = vectorList;
}
public void run() {
// do something with names, for example, query database
Result result = process names;
//add result to vectorList
vectorList.add(result);
}
}
So, based on the example above, I want to make thread pool for each data I have in the request, run it simultaneously, and add result to VectorList.
And at the end of the process, I want to have all the result already in the Vector list.
I keep getting inconsistent result in the response.
For example, if I pass request with 10 names, I am getting back only 3 or 4, or sometimes nothing in the response.
I was expecting if I pass 10, then I will get 10 back.
Does anyone know whats causing the problem?
Any help will be appreciate it.
Thanks
The easy solution is to add a call to ExecutorService.awaitTermination()
public static void main(String[] args) {
//Assume that I have request object that contain arrayList of names
//and VectorList is container for each request result
ExecutorService threadExecutor = Executors.newFixedThreadPool(3);
Vector<Result> vectorList = new Vector<Result();
for (int i=0;i<request.size();i++) {
threadExecutor.execute(new QueryTask(request.get(i).getNames, vectorList)
}
threadExecutor.shutdown();
threadExecutor.awaitTermination(aReallyLongTime,TimeUnit.SECONDS);
response.setResult(vectorList)
}
You need to replace threadExecutor.shutdown(); with threadExecutor.awaitTermination();. After calling threadExecutor.shutdown(), you need to also call threadExecutor.awaitTermination(). The former is a nonblocking call that merely initiates a shutdown whereas the latter is a blocking call that actually waits for all tasks to finish. Since you are using the former, you are probably returning before all tasks have finished, which is why you don't always get back all of your results. The Java API isn't too clear, so someone filed a bug about this.
There are at least 2 issues here.
In your main, you shut down the ExecutorService, then try to get the results out right away. The executor service will execute your jobs asychronously, so there is a very good chance that all of your jobs are not done yet. When you call response.setResult(vectorList), vectorList is not fully populated.
2. You are concurrently accessing the same Vector object from within all of your runnables. This is likely to cause ConcurrentModificationExceptions, or just clobber stuff in the vector. You need to either manually synchronize on the vector inside of QueryTask, or pass in a thread-safe container instead, like Collections.synchronizedList( new ArrayList() );

Categories

Resources