How to pause input when using Thread.sleep in Java - java

When I pause the execution in my program with Thread.sleep, it seems that the program is still able to get input, even while it is being paused. Is there any fix to this? I am using Java 2 and I've looked through so many forums, but couldn't find a suitable answer.
This is the code I'm using to pause my program:
Thread.sleep(2000);
int input = c.readInt();

Your program does not control the terminal device. You can see what you type because the software that actually controls the device is reading keyboard input and writing it to the screen. Your program is not getting any input while it's in sleep.
What actually controls the terminal window or device depend on operating system, and things get complicated when dive into the details. For example on Unix, it's handled by a a thing called "line discipline". The default ("canonical") setting lets you edit lines of text before they are sent to your programs. It also intercepts key combinations like control-c and control-z for job control. Further reading: https://en.m.wikipedia.org/wiki/POSIX_terminal_interface

Related

Java JSyn Loopstation

I'm trying to program a loopstation program in JSyn inspired by something like this. The idea is, that I can record to Wav-files and play them from the program. That worked well until I attempted to do this for multiple files simultaneously.
How do I approach this?
I cannot create multiple synthesizer engines otherwise I get an error, so I have created a class with my line out and my synthesizer. But if the audio only plays while the synthesizer sleeps, how can I play from multiple files at once?
System.out.println("queue the sample");
samplePlayer.dataQueue.queue(sample);
System.out.println("queued the sample");
// Wait until the sample has finished playing.
do {
mySynth.sleepFor(1); //synth has to sleep while sample is being played
} while (samplePlayer.dataQueue.hasMore()); //this seems to always return true -> synth never wakes up & the program crashes
This is adapted from the examples included in the JSyn library. I have based most of my own coding on the JSyn Programmer's Guide
This is what the GUI looks like (programmed in Java Swing). It responds to the mouse and the numpad. This works.
The constructor of my output class. This contains the synthesizer and line out.
public OutputMix() {
filePath = sampleMachineFrame.filePath; //string containing path to location for sample files
mySynth = JSyn.createSynthesizer();
myLineOut = new LineOut();
mySynth.add(myLineOut);
recorder = new RecordMic[10]; //one recorder for each button (my own class)
player = new PlayFromWav[10]; //one player for each button (my own class)
}
The recording works absolutely fine. I can even start overlapping recordings (i.e. record to two files at once) and play them with an external program.
But when I try to play them back the synthesizer never wakes up and I am also struggling to imagine how I would play multiple files at once.
Thanks for your help :)
In general, you do not want to sleep in your program unless you are sequencing events. Just queue samples in response to Button events and let them run.
If the files are small enough then you can just load them into memory. Then you can queue multiple files any time you want. You might need to increase the heap size of your Java virtual machine.
Here is an example: https://github.com/philburk/jsyn/blob/master/tests/com/jsyn/examples/PlaySample.java
If the samples are too big then you will have to stream them off the disk using multiple threads, which is more difficult.
You can make all the samples the same size. Then they will stay in phase. Or you can trigger them at specific beats using timestamps.

Get notification when external application is fully running - Java

I am writing a program in java which can start up applications such as, for example, firefox.
Edit: This program is for linux, specifically ubuntu.
It's easy to start the program:
Runtime.getRuntime().exec("/usr/bin/firefox");
However, I want to retrieve details from the window once it is fully opened or running.
At the moment I'm just calling:
Thread.sleep(delay);
To make sure the window is ready, but this is a poor solution. Different windows requiring different delays is a problem.
Messy.
So my question is, is there any way that I can be notified when firefox (or any other external application for that matter) is fully setup? I don't think I could use Process.waitFor() because the Process won't be finished until firefox is closed.
Thanks in advance!
Update: Process.waitFor() doesn't work. I have tried it and it only returns when firefox is closed, not when it is fully setup. Just for anyone trying it themselves, if another firefox window is already open it will work (which fooled me at first) but if there is no existing window it won't!
You can use Process#waitFor to wait till the command gets executed and then check the exitValue like this:
Process p = Runtime.getRuntime().exec("/usr/bin/firefox");
p.waitFor();
if(p.exitValue()==0) {
//success
} else {
// fail read error stream or out stream for possible causes
}
Ok I have been doing some more thinking and I have a reasonably satisfactory answer.
Instead of waiting until the window is ready, continually search for it with xdotool:
while(line == null){
writer.write("xdotool search --onlyvisible --name " + name + "\n");
writer.flush();
if(reader.ready())
line = reader.readLine();
Thread.sleep(1000);
}
xdotool will only print a string if it finds a window called name.
So if the reader is ready() then you know the window is open.
The Thread.sleep() is necessary because if it is not present xdotool will spit out a bad window error and the reader will read that.
However, it seems to almost be faster to use a standard delay like I spoke about above but this solution will work even for windows which take longer to load, rather than trying to guess a delay.

How to end inputstream.read in java

I am trying to read data from 5 devices connected serially. My Java code is running fine if the device is healthy, if not then inputstream.read() hangs the program and does not allow further execution.
I have tried using inputstream.available(), BufferedInputStream... but nothing works.
What I want to do is: if a device does not respond my code, it should end itself and let the control go to the main program where it will go to the next device. The socket remains open for one cycle of polling.
Socket es = new Socket("10.12.90.153",4001);
OutputStream osnew= es.getOutputStream();
InputStream isnew = new BufferedInputStream(es.getInputStream());
This is done in the task program, then I pass osnew and isnew to each device at a gap of one second for further action. The osnew writes some data to which the device responds. Then I read from isnew...This where the program hangs.
InputStream is designed to block when you try and read data and none is available. You could call the available() method to see whether any data is available to read without blocking, but this only works one way - if available() returns non-zero you know you can read without blocking, but if it returns zero you won't necessarily be blocked. It is perfectly valid for an input stream to always return zero from available().
You may wish to look into the non-blocking I/O APIs of java.nio instead of using streams.
You could handle each device in a separate thread. That way your program will stay responsive even when the devices aren't. But be aware of the pitfalls of multithreaded programming.
More information about multi-threaded programming in Java can be found on http://docs.oracle.com/javase/tutorial/essential/concurrency/
How are you reading from the device? I'll assume you're using some form of FileInputStream to do it. That class looks to be suitable for reading from a filesystem to me, but a device, which could block for a long period of time is likely to lock up the Java thread until the device does respond. You need to make some kind of timed read request of the device, and I don't know of any Java class that does that.
Best suggestion I have is to write some JNI code that talks nicely and doesn't block when your devices stop responding. This is what I did when I was talking to a USB device. If I were coding this (for Linux) I would use select (which has a time period argument) to wait of an input from any of the devices.

Why does a dialog seemingly have its one thread?

I'm new to advanced programming - but from what I've read, all my android programs are on one thread.
This means, only one line of code or method/function can be executed at a time before moving on to the next line (that's what I thought anyway).
However, I'm using a custom dialog to develop this application and yet, the program continues even after the dialog has ran. I'd like my program to wait for the dialog to close so that I can receive the input and manipulate it.
This seems fairly straightforward when programming in Java (e.g. the Scanner tool waits for the user input before proceeding as opposed to running the code following it while it waits for user input).
How can I do this?
Everything does happen on one thread unless you explicitly tell it not to. However, showing a Dialog happens asynchronously. Basically, when you ask the Dialog to show, it adds that information to a list of UI events that are waiting to happen, and it will happen at a later time.
This has the effect that the code after asking the Dialog to show will execute right away.
To have something execute after a Dialog choice is made, add an onDismissListener to the dialog and do whatever it is you want to do in onDismiss.

Java: What's the reason behind System.out.println() being that slow?

For small logical programs that can be done in a text editor, for tracing I use the classic System.out.println().
I guess you all know how frustrating it is to use that in a block of high number of iterations. Why is it so slow? What's the reason behind it?
This has nothing whatsoever to do with the JVM. Printing text to screen simply involves a lot of work for the OS in drawing the letters and especially scrolling. If you redirect System.out to a file, it will be much faster.
This is very OS-dependent. For example, in Windows, writing to the console is a blocking operation, and it's also slow, and so writing lots of data to the console slows down (or blocks) your application. In unix-type OSes, writing to the console is buffered, so your app can continue unblocked, and the console will catch up as it can.
Ya, there is a huge amount of overhead in writing to the console. Far greater than that required to write to a file or a socket. Also if there are a large number of threads they are all contending on the same lock. I would recommend using something other that System.out.println to trace.
This has nothing to do with Java and JVM but with the console terminal. In most OSes I know writing in the console output is slow.
Buffering can help enormously. Try this:
System.setOut( new PrintStream(new BufferedOutputStream(System.out)) );
But beware: you won't see the output appear gradually, but all in a flash. Which is great, but if you're using it for debugging, and the program crashes before it terminates, in some circumstances it's possible you won't see the text printed just before the crash.
This is because the buffer wasn't flushed before the crash. It was printed, but it's still in the buffer, and didn't make it out to the console where you can see it. I remember this happening to me, in a puzzling debug session. It's best to occasionally flush explicitly, to make sure you see it:
System.out.flush();
Some terminals just are faster than others. This may vary even within one operating system.
This might look as it doesn't directly answer your question, but my advice is to never use System.out for tracing ( if you mean by that a kind of debugging, in order just to see the advance of your app )
The problems with System.out for debugging are several :
once the app ends, when you close the console you'll loose the log
you'll have to remove those statements once your app is working properly ( or comment them ). Later if you want to reactivate them, you'll have to uncomment/comment again ... tedious
I recommend instead to use log4j and "watch" the log file, either with a tail command - there's also a Tail for Windows - either with an Eclipse plugin like LogWatcher.
One interesting thing I've noticed about writing to the terminal (at least in Windows). Is it actually runs much much faster if the window is minimized. This is definitely closely tied with Michael Borgwardt's answer about drawing and scrolling. Really if you're logging enough to notice the slowdown you're probably better off writing to a file.
The slowness is due the large amount of Java-Native transitions which happen on every line break or flush. If the iteration has to many steps, the System.out.println() isn't much of a help. If the iteration steps are not that important by themselves, you may call System.out.println() on every 10 or 100 steps only. You can also wrap the System.out into a BufferedOutputStream. And of course there is always the option to asynchronize the print via ExecutorService.

Categories