I'm trying to execute a thread inside my JavaFx application and I also need to update my listview, reason why I used a Platform.runLater inside it. The problem is that it seems to be too slow, since it jumps the if state inside it. The listView.setItems(model.getEmailList()); part is executed without problem, but ignore the the condition even if when I print the two value I wanna compare they are different. How can I improve it? Because I cannot move that if outside the Platform since I'm trying to display it in a thread of my JavaFX application.
new Thread() {
#Override
public void run() {
while (true) {
try {
int currentOnServer = model.askNumbOfEmail();
if (emailForClient != currentOnServer) {
model.reLoadData();
Platform.runLater(() -> {
listView.setItems(model.getEmailList());
if (currentOnServer > emailForClient) {
new Alert(Alert.AlertType.INFORMATION, "Hai recevuto un email!").showAndWait();
}
});
emailForClient = currentOnServer;
}
} catch (IOException ex) {
Thread.currentThread().interrupt();
return;
} catch (ParseException ex) {
System.out.println("ParseException ERROR!");
}
}
}
}.start();
Your if statement doesn't work because you're changing part of the condition in a separate thread:
emailForClient = currentOnServer
This is a common problem when you're working with threads. You need to modify the logic of your code to facilitate parallel execution. You can create a temp variable to store emailForClient and use it inside Platform.runLater instead:
model.reLoadData();
final int currentEmail = emailForClient; // I'm assuming emailForClient is an int
Platform.runLater(() -> {
listView.setItems(model.getEmailList());
if (currentOnServer > currentEmail) {
new Alert(Alert.AlertType.INFORMATION, "Hai recevuto un email!").showAndWait();
}
});
emailForClient = currentOnServer;
Related
I have Java Applet and I run file selection method from JavaScript.
Since security does not allow doing this I have a thread which monitors boolean flag
Thread uploadFilesThread = new Thread(() -> {
try {
while (true) {
synchronized (_UploadFilesSyncObj) {
_UploadFilesSyncObj.wait();
if (uploadFiles) {
uploadFiles = false;
ProcessFiles();
}
}
}
} catch (Exception ex) {
// TODO
}
});
uploadFilesThread.start();
Inside this method I upload selected files. I want to have Cancel logic and after each uploaded file I check appropriate flag.
volatile boolean _CancelRequested = false;
for (JFileInfo fileEntry : _SelectedFilesList) {
try {
synchronized (_CancelSyncObj) {
if (_CancelRequested) {
JOptionPane.showMessageDialog(null, "FOR Cancel Requested");
break;
}
}
...
Method which sets flag is:
public void Cancel() {
synchronized (_CancelSyncObj) {
_CancelRequested = true;
}
}
I know that method Cancel is called from javaScript for sure and if I put there notification window it will be shown. However cancel is not processed by "Uploader" thread and files uploading continues.
I've tried it without volatile and without synchronized, sometimes it can be processed but result is not stable (and it's correct as I understand without volatile and synchronized).
I'm new in Java and will appreciate any advice.
Use a semaphore instead of the volatile variable, and it will work reliably.
Here is the long story about volatiles:
https://www.ibm.com/developerworks/java/library/j-jtp06197/index.html
Here is sample code for Semaphores:
https://www.geeksforgeeks.org/semaphore-in-java/
I've been trying to figure it out for some time,
I'm trying to write a chat - server app, just for learning.
I have an obstacle that I cannot understand,
The while loop inside of the GUI class freeze, but just when it trying to read:
public void run(){
Platform.runLater(() -> {
do {
try {
msg = getFromServer.readUTF(); // <--- freeze GUI
chatWindow.appendText(msg);
} catch (IOException e) {
e.printStackTrace();
}
} while (true);
});
}
You can see that it's running in a thread, but i did try to run it in other ways...
Only the DataInputStream make it stuck,
msg = getFromServer.readUTF();
And this it the methud that it's coming from:
public void connectToServer(){
try {
serverConectionState = new Socket("127.0.0.1", 6789);
getFromServer = new DataInputStream(serverConectionState.getInputStream());
sendToServer = new DataOutputStream(serverConectionState.getOutputStream());
onlineOffline.setText("Online");
onlineOffline.setTextFill(javafx.scene.paint.Color.web("#0076a3"));
} catch (IOException ex){
chatWindow.appendText("server connection fail\n");
}
}
This class, is the Controller.class - if it's make any diffrent.
My first question in stackoverflow, after a lot of help from the community.
Thanks in advance
I'm assuming the run method you showed is part of a Runnable that is executed in a background thread.
You are running the entire loop on the FX Application Thread (by using Platform.runLater()). So you block that thread and prevent it from repainting. You should run only the UI updates on the FX Application Thread:
public void run(){
do {
try {
String msg = getFromServer.readUTF(); // <--- freeze GUI
Platform.runLater(() -> chatWindow.appendText(msg));
} catch (IOException e) {
e.printStackTrace();
}
} while (true);
}
instead of using platform.runlater you should use java task, so that you can run the code in different thread, without freezing the UI thread
I have a thread created inside a secondary activity on Android, like so:
new Thread(new Runnable() {
public void run() {
try {
String branch=spinner.getSelectedItem().toString();
while( branch.equals(spinner.getSelectedItem().toString())){
System.out.println("----LOOPER."+spinner.getSelectedItem().toString());
GetQinfo a= (GetQinfo) new GetQinfo().execute(city,type,org,spinner.getSelectedItem().toString());
Thread.sleep(refreshRate);
}
} catch (InterruptedException e){
e.printStackTrace();
}
return;
}
}).start();
the problem is that when i go back to the main activity this thread is still running.
what i did was on the goback button to write this:
spinner.setSelection(0);
this.finish();
This way the value of the spinner is changed, causing the while loop on the thread to return false, thus exiting the thread.
But i dont think this is the right way of doing it. can anyone suggest something different, or should i say, better
You should use interrupt() method of the thread when you leave the activity.
YourThread.interrupt();
new Thread(new Runnable() {
public void run() {
try {
if(!Thread.interrupted())
String branch=spinner.getSelectedItem().toString();
while( branch.equals(spinner.getSelectedItem().toString())){
System.out.println("----LOOPER."+spinner.getSelectedItem().toString());
GetQinfo a= (GetQinfo) new GetQinfo().execute(city,type,org,spinner.getSelectedItem().toString());
Thread.sleep(refreshRate);
}
} catch (InterruptedException e){
e.printStackTrace();
}
return;
}
}).start();
There is no method explicitly available to stop a thread. There were methods previously to stop the thread but they were deprecated. Please read the following link to see why the developers of java wanted it this way: http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
According to this document, they prefer that you do it in the manner that you suggested. So you're not wrong.
private volatile boolean stopThread;
public void run() {
String branch=spinner.getSelectedItem().toString();
while (!stopThread) {
System.out.println("----LOOPER."+spinner.getSelectedItem().toString());
GetQinfo a= (GetQinfo) new GetQinfo().execute(city,type,org,spinner.getSelectedItem().toString());
Thread.sleep(refreshRate);
}
}
public void stopThread() {
stopThread = true;
thread.interrupt();
}
If run() hasen't finished and is recalled from outside I need to finish the running shread first.
public class EnvTime extends Thread {
public void run() {
long step = 2000 / benvelope1.length;
while (!finished) {
for (int i = 0; i < benvelope1.length; i++) {
envOut = benvelope1[i];
try {
Thread.sleep(step);
} catch (InterruptedException benvelope1) {
benvelope1.printStackTrace();
}
}
}
}
}
So I call this code from another method with:
Env interpol;
interpol.interrupt(); //
interpol=new EnvTime();
interpol.start();
But this is not working...
It's not clear what you're trying to achieve, but by doing
Env interpol;
interpol.interrupt(); //
you'd probably get a NullPointerException. If you want your code to reach the
} catch (InterruptedException benvelope1) {
...
}
you need to make sure the thread is in the try-block, specifically in the Thread.sleep method when you interrupt it.
In other words, you at least need to start the thread before interrupting it.
You should change finished somewhere in your code.
Like this way:
try {
Thread.sleep(step);
} catch (InterruptedException benvelope1) {
finished = true;
benvelope1.printStackTrace();
}
Maybe you should also wait that the thread is really terminated before starting the new one. Use join:
interpol.interrupt();
interpol.join();
interpol=new EnvTime();
interpol.start();
This question already has answers here:
How to start/stop/restart a thread in Java?
(9 answers)
Closed 7 years ago.
I have created a program which searches for files in a source folder. If it finds any file, it processes that file and moves it to a destination folder, then looks for a new file in the source folder. It has to keep on checking the source folder for a file.
I have used a thread to look for files in the source folder. The problem I am facing is whenever any exception is thrown during file processing, the thread gets stopped. I want the thread to be running even if an exception is thrown. It has to move the file that caused the error to some other folder and look for a new file in the source folder. How can I make the thread keep on running?
Eg:
public void run() {
try {
searchfile();
}
catch(Exception e) {
e.printStackTrace();
}
}
public void searchfile(){
...
}
Update :
I should be more clear in my question. Actually there are 4 source folders and 4 destination folders. I have to perform the same operation in each source & destination pair. So i have created 4 threads in one class and do the operation in separate class.
class MainClass
{
public static void main(String[] args){
for(int i=0;i<4;i++){
SearchClass search = new SearchClass();
Thread thread = new Thread(search);
thread.start();
}
}
}
class SearchClass
{
public void run() {
try {
searchfile();
} catch(Exception e) {
e.printStackTrace();
}
}
public void searchfile(){ ... } }
All the thread wont stop running eventhough it caught any exception in middle. How can i do that?
If a thread is dying due to an uncaught exception, the answer is simple: catch the exception at an appropriate place so that you can keep going. Either catch the exception within your searchfile method, or make the run method call searchfile in a loop.
If you want your thread to keep running use a loop.
public void run() {
while(!Thread.interrupted())
try {
searchfile();
}
catch(Exception e) {
e.printStackTrace();
}
}
Inside your catch, you can move the file to the error folder then create a new object of the same thread and start it again.
unless i got you wrong, your code is missing the "keep running" nature, i.e. you need to have a loop somewhere:
public static void main(String[] args){
ExecutorService service = Executors.newFixedThreadPool(4);
// for each of your 4 folders
while (true) {
Future<File> searchResult = service.submit(new SearchTask());
try {
File foundFile = searchResult.get();
// handle found file
} catch (Exception e) {
// handle exception
}
}
}
private static class SearchTask implements Callable<File> {
#Override
public File call() {
return searchFile();
}
public File searchFile() {
// search & return found file
}
}
note that this is just a very simple extension of your example. it is still missing the parametrization of the SearchTask to actually be specific for a folder, handling of files & exceptions, etc. as mentioned in previous answers, your SearchTask should implement Runnable (i prefer Callable...), and IMHO it's always better to use an ExecutorService than to spawn threads manually. hope this helps...
I'm not entirely sure if this will work, yet here's a try.
public void run() {
try {
searchFile();
} catch(Exeption e) {
e.printStackTrace();
if(!Thread.currentThread().isAlive())
Thread.currentThread().start();
}
}
you said that the exception may be thrown during file process , so i put the processFile() in a try-catch block. but if it may be thrown during search, you may put it in a try-catch too.
public void run() {
while(!terminated) {
findNextFile();
try {
processFile();
} catch {
// handle error
}
}
}
Here are my assumptions based on your question and your clarification:
Each thread, in the run() method, only calls searchfile() once and not in a loop
your searchfile() method has a loop in it and you want that loop to continue running even if an exception is thrown in it.
you have some way of initializing each thread that you aren't showing us (and that isn't terribly important for this specific quiestion)
searchfile() does not declare that it throws any Exception
You aren't using a logging framework, but are instead using System.out (although using a logging framework is a Really Good Idea
Java 5 is OK (otherwise you'll have to use a different for() loop below
With these assumptions, you don't want to plan to catch an Exception in your run() method except for the purpose of logging that something went very wrong:
public void run() {
try {
searchfile();
} catch (RuntimeException e) {
System.out.println("Something went very wrong! Unexpected RuntimeException");
e.printStackTrace();
}
}
Note that the code catches RuntimeException. Always catch the most specific Exception that will do what you need. Then what you need is something such as the following in your searchfile() method:
File[] files = directory.listFiles();
for (File file : files) {
try {
// Do your normal file/directory processing here
} catch (Exception e) {
System.out.println("Exception processing file " + file.getName() + " " + e);
// Move "file" to another area
}
}
Since you are trapping unexpected Exceptions in the main loop of your Thread, your thread will continue processing after handling the Exception.
You can easily go with a workaround. Just run the needed logic for some amount of times and finish the job based on some criteria.
public class ThreadRestartWorkaround extends Thread {
public static void main(String[] args) {
ThreadRestartWorkaround th = new ThreadRestartWorkaround(5);
th.start();
}
private int maxCycles;
private int currentCycle;
public ThreadRestartWorkaround(int maxCycles) {
this.maxCycles = maxCycles;
}
#Override
public void run() {
while(executeSomeLogicUntilReachingTheLimit());
System.out.println("Finished due to exceeding the maxCycles config");
}
private boolean executeSomeLogicUntilReachingTheLimit() {
currentCycle++;
System.out.println("Executing logic for " + currentCycle + " time");
return currentCycle < maxCycles;
}
}
And the output is
Executing logic for 1 time
Executing logic for 2 time
Executing logic for 3 time
Executing logic for 4 time
Executing logic for 5 time
Finished due to exceeding the maxCycles config