wait() before next iteration in a for loop java - java

What I'm trying to do here is to upload files one by one. For example, if my file list contains 2 files ready to upload, I want to upload the second file once the first is uploaded and created.
Actually, I loop the file list and upload the file from each iteration whitout waiting the last upload to finish.
Here is an idea of what I'm excepecting :
for(FileContainerBean fileContainer:fileContainerList){
FileUpload fileUpload=new FileUpload(fileContainer.getFile());
Thread th=new Thread(fileUpload);
th.start();
//Now i want here to wait beafore moving to the next iteration
while(!fileContainer.isCreated(){
wait();
}
if(fileContainer.isCreated(){
notify();
}
}
fileContainer is a bean with getters and setters (setFile,getFile,isCreated....).
When the upload is over and the file is created ( HttpResponseCode=201), fileContainer.isCreated=true. Initially, isCreated=false;
I hope that I'm clear enough ! So is it possible to do that ?
Thanks in advance !
Ismail

So you basically want to continue the execution only after the th thread is finished? Just don't run it in a separate thread, but rather:
for(FileContainerBean fileContainer:fileContainerList){
FileUpload fileUpload=new FileUpload(fileContainer.getFile());
fileUpload.run();
// continues after the file is uploaded
}
If you want to keep this in a separate thread after all (as you said in a comment), then execute the whole loop in the background:
Runnable uploadJob = new Runnable() {
public void run() {
for(FileContainerBean fileContainer:fileContainerList){
FileUpload fileUpload=new FileUpload(fileContainer.getFile());
fileUpload.run();
// continues after the file is uploaded
}
}
};
new Thread(uploadJob).start();

You should set the notify() in the run method of Thread th so after the new thread finish the upload, it will notify the waited thread.
Or I see that you want your main thread to wait until the upload process completed, so why don't you simply make your program single threaded.
I mean don't initiate the upload process in a new thread, because the default behavior then is wait until the current upload is finished then start the second upload and that is what you want.

Do like this
while(true){
if(fileContainer.isCreated()){
break;
}
}

Related

JavaFX 8 initialize method

So I am trying to do a chat type program using JavaFX for the GUI. I have it so a class that acts as a server will loop and keep adding client connections to it.
public void serverconnection()
{
// portnumber was saved from constructor
try (ServerSocket socket = new ServerSocket(this.portnumber))
{
// loop is a bool set to true
while (loop)
{
// this class extends Thread and has its own overwritten start method
new myclass(socket.accept()).start();
}
}
catch (IOException e)
{
System.exit(404);
}
}
so the problem is (I am assuming) was, this loop keeps looping until the program closes. but since I was calling this within the JavaFX's initialize method
public void initialize(URL url, ResourceBundle rb)
{
// constructor, nothing here is needed for this post
myclass z = new myclass(45234);
// problem here, since this has a loop, but
z.serverconnection();
// gui wont load till after this is done
// but serverconnection is only done after program ends
}
the problem with this is, apparently, the GUI will not load until AFTER initialize has finished, but it will not finish until program closes. After google searching, I could not find any fix for this. I need a way to call a method that will do all this, AFTER initialize method has finished. My client side class is similar to this, but the methods to connect on that are activated on events when clicking a login button. For this serverside one, I am trying to start without any interaction with the user. so is there a way to call a method or make this work AFTER initialize method has ran?
You might want to run this loop in a thread, so do something like
Thread t = new Thread(z::serverconnection)
t.start()
If you do this at the end of your initialization() method, it will run exactly then.
This will start a thread which runs forever; you might want to add a feature for interrupting the thread when the program is supposed to be terminated.
Remember that for changing anything in the GUI you need to sumbit a task via Platform.runLater(). This is because the GUI may only be modified from within that one thread. So in order to modify anything, you have to wrap that in a Runnable and submit it for execution.
You can do that in this way:
Platform.runLater(new Runnable() {
#Override
public void run() {
doWhateverNeedsToBeDone();
}
});
In Java 8, you can do anything of the following, depending on the extent of the work to be done:
Platform.runLater(() -> {
doWhateverNeedsToBeDone();
});
Platform.runLater(() -> doWhateverNeedsToBeDone());
Platform.runLater(this::doWhateverNeedsToBeDone);
The latter only works if doWhateverNeedsToBeDone() is a method of this.

Check for existing file with a loop

I'd like to check for an existing file using a while loop. Now the problem is, that if use something like this:
while (file.exists()) {
text.setText("Some text appears");
text.setTextColor(Color.RED);
}
my program always seem to not to respond at all. Is it because my loop is somehow an infinite loop? Or why is is not working correctly.
Right now, i am using a simple if statement but i don't like it that way, because it is not updated right away when the file exists.
EDIT:
What i want is:
I offer a file to download. In my app, there is a text which says "Not Available yet". I want to change the text right after the file exists to something like "File is Available".
If you want to check periodically if a file exists, you have to do this with an asynchronous task or a timer.
TTimerTask task = new TimerTask() {
#Override
public void run() {
// Here you do whatever you want
}
};
Timer timer = new Timer();
timer.schedule(task, 0,30000);
This will check the file every thirty seconds.
You can find more info on http://www.mkyong.com/java/jdk-timer-scheduler-example/
Your program goes in an infinite loop as the condition inside while loop will always be true if the file is present..
You need to check like this:
File file = new File(subDir.getPath() + "somefile.txt");
boolean exists = file.exists();
if (!exists) {
// It returns false if File or directory does not exist
}
else
{
//Update here
}
And if you want to check it inside the loop then try like this:
while (true)
{
File file = new File(subDir.getPath() + "somefile.txt");
boolean exists = file.exists();
if (!exists) {
// It returns false if File or directory does not exist
return;
}
else
{
//Update here
}
}
If the file exists, then it'll pop into the while loop and will keep on looping because the file exists, you'll have to make the file non-existable within the while loop...
Best thing for you to do, is get your program working without the while loop... as you mentioned with an IF function, then slowly over time implement (Test) a new function (while loop) into the equation.
What you need to fix in the while loop is... What happens to the file when it enters the loop and how does it get out of the loop. Current standing is, it doesn't as the file still exists.
Ok so whenever the other person is checking for the file does the program exit if the file doesn't exist? I mean you can't just have it checking for the file forever. I suppose you could put it in a Thread and run it with a slight wait inside the while loop but the overhead... sheesh!
Is this a specific screen inside your program? Is the person suppose to be able to exit this "file found/not found" page? I could probably write a snippet but I need more info. :)

Swing thread communication

I am creating a small swing application which plots a set of points given in a file. Guidelines suggested me to invoke a new thread for the GUI, for which I used the following code.
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new View().setVisible(true);
}
});
One of the scenario in the application is to open a file (which is done using a JFileChooser).
private void openMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
int returnVal = fileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
//some heavy operations
} else {
System.out.println("File access cancelled by user.");
}
}
There are some heavy operations that are needed to be done, before proceeding to plot the points.
My questions are, is it advisable to place heavy codes in the GUI thread ? Is it possible to send the file object to the main thread for processing and send the results to GUI thread ?
Please note that I have no idea about Java Threading API.
use SwingWorker
SwingWorker proposes a way to solve it by performing the time-consuming task on another background thread, keeping the GUI responsive during this time.
take a look at this
http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html
http://www.theeggeadventure.com/wikimedia/index.php/SwingWorker_Example
http://weblogs.java.net/blog/mkarg/archive/2010/01/03/did-you-know-swingworker-can-send-progress-status
http://www.javaworld.com/javaworld/jw-06-2003/jw-0606-swingworker.html
If the result of the long running task modifies a Swing component, you can use SwingWorker. For more information, please see Worker Threads and SwingWorker.

Android views can not be touched by other threads?

I am a newbie in Android and creating a mini FTP download manager for myself.. I am using multithreading, each thread to handle one download or upload. In the MainActivity.java, I am using two spinners in the view. One to list the files on the server (which can be downloaded), another to list files on my phone folder (which can be uploaded). I want to update the first (download) spinner when a new file is uploaded, and the second (upload) spinner when a new file is downloaded. However I am not able to make out how to update the spinners only when the corresponding threads finish their job. I created methods to update the spinners in the MainActivity.java and tried to call them in the end of the run() of the threads, so that they'l be updated once the threads finish downloading/uploading. However, I am getting an error in LogCat saying
android.view.ViewRoot$CalledFromWrongThreadException : Only the original thread that created a view hierarchy can touch its views.
The method for updating upload spinner is:
void upScrollUpdate() {
spinup=(Spinner)findViewById(R.id.uploadspin);
spinup.setEnabled(false);
String[] upload={"No Files"};
File sdDir=Environment.getExternalStorageDirectory();
File dir=new File (sdDir.getAbsolutePath() + "/aFTP");
File[] fArray=dir.listFiles();
if(fArray.length>0) {
upload=new String[fArray.length];
}
for(int i=0;i<fArray.length;i++) {
upload[i]=fArray[i].getName();
}
ArrayAdapter<String> saaUpload=new ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item,upload);
spinup.setAdapter(saaUpload);
if(spinup.getSelectedItem().toString().equalsIgnoreCase("No Files")) {
uploadButton.setEnabled(false);
}
spinup.setEnabled(true);
}
Why cant this method be called from another thread, and what is the other way out of this, I simply want to update the spinners but I have spent a whole day on this only thing...
For any piece of code that will update the UI, put that in this block:
Refer to this link for more info on runOnUiThread
runOnUiThread(new Runnable() {
public void run() {
// RUN THE CODE WHICH IS GIVING THAT EXCEPTION HERE
}
});
The same can also be done like this:
Runnable run = new Runnable() {
#Override
public void run() {
// RUN THE CODE WHICH IS GIVING THAT EXCEPTION HERE
}
}; YourActivity.this.runOnUiThread(run);
Alternatively, you can make use of an AsyncTask. You can do your processing in the doInBackground() method and then update the Spinners in the onPostExecute() method of the AsyncTask
EDIT: Check these tutorials to help you get started with using AsyncTask:
http://www.vogella.com/articles/AndroidPerformance/article.html#asynctask
http://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/
http://android10.org/index.php/articlesother/239-android-application-and-asynctask-basics
http://mobileorchard.com/android-app-developmentthreading-part-2-async-tasks/
http://thenewboston.org/watch.php?cat=6&number=101
The 5th link to thenewboston.org has about 200 odd video tutorials on YouTube here: http://www.youtube.com/course?list=EC2F07DBCDCC01493A&feature=plcp
EDIT 2: Check the edit in this link here: https://stackoverflow.com/a/13265776/450534
It is at the bottom of the answer.
Anything to do with views should be done on UI thread.
You can use activityInstance.runOnUIThread() to handle this scenario of updating views from different thread.
Refer: Android: RunOnUiThread vs AsyncTask

How can I schedule a particular thread in Blackberry

I want to auto-schedule a thread with a particular time interval. I also need to execute this in the background continously without hangs to the device.
I have tried this with Application Manager Class but it's for application scheduling and I need to schedule thread within the application.
I would use TimerTask:
public class MyScreen extends MainScreen {
private Timer mTimer;
public MyScreen() {
mTimer = new Timer();
//start after 1 second, repeat every 5 second
mTimer.schedule(mTimerTask, 0, 5000);
}
TimerTask mTimerTask = new TimerTask() {
public void run() {
// some processing here
}
};
}
see BlackBerry API Hidden Gems (Part Two)
use UiApplication.getUiApplication().invokeLater()
it accepts a delay and repeat parameters and will perform exactly what you need.
EDIT
I know this post is old but this is by far the best option to schedule repeating events and I would like to add that to stop the scheduled event the following is required:
//Start repeating "runnable" thread every 10 seconds and save the event ID
int eventId = UiApplication.getUiApplication().invokeLater(runnable, 10000, true);
//Cancel the repetition by the saved ID
UiApplication.getUiApplication().cancelInvokeLater(eventId);
Assuming you want it to run a thread on device startup:
Create a second project and list it as an alternate entry point.
In your UiApplication or Application main(), check the argument passed to the project. Do your periodic stuff there via Thread.sleep and don't call enterEventDispatcher.
search for "autostart":
http://docs.blackberry.com/en/developers/deliverables/1076/development.pdf
Or if you want to do something once a user "starts" it, then look into creating a new thread to do your timing stuff. Override your screen's onClose() and use Application.getActivation().deactivate() to throw the screen into the background.
Or there's a other ways to do something like this like invokeLater, etc. Maybe eventlisteners may do what you need, but you didn't give a lot of details.
As long as the application is running - just create the thread and after each bit of work call Thread.sleep for as long as you need it to stay dormant.
If you need it to wake up at a particular time, rather than just sleep for a particular time, then you can do something like the following:
Date wakeUpAt = ...; // Get this however
Date now = new Date();
long millisToSleepFor = wakeUpAt.getTime() - now.getTime();
Thread.sleep(millisToSleepFor);

Categories