Reputation: 55755
I have a thread that executes the following code:
public void run() {
try {
int n = 0;
byte[] buffer = new byte[4096];
while ((n = in.read(buffer)) != -1) {
out.write(buffer, 0, n);
out.flush();
}
} catch (IOException e) {
System.out.println(e);
}
}
where in
is System.in
. How can I stop such thread gracefully? Neither closing System.in
, nor using Thread.interrupt
appear to work.
Upvotes: 22
Views: 22715
Reputation: 31
Is it safe to close in stream in other thread?
It works for me. In this case, in.read(...)
throws exception SocketException
.
Upvotes: 2
Reputation: 156
I had the same problem today, and this is how I fixed it, using in.ready()
:
public void run() {
String line;
// Some code
while(!Thread.currentThread().isInterrupted()){
try {
if (in.ready()) {
line = in.readLine();
}
} catch (Exception e) {
try {
Thread.currentThread().wait(500);
} catch (InterruptedException e1) {
// Do what we want when thread is interrupted
}
}
}
}
Upvotes: 0
Reputation: 19187
You've stumbled upon a 9 year old bug no one is willing to fix. They say there are some workarounds in this bug report. Most probably, you'll need to find some other way to set timeout (busy waiting seems unavoidable).
Upvotes: 8
Reputation: 114847
If you want to give a user some time to enter data - maybe to allow overriding default values or interrupting some automated process -, then wait first and check available input after the pause:
System.out.println("Enter value+ENTER within 5 Seconds to override default value: ");
try{
Thread.sleep(5000);
} catch {InterruptedException e){}
try{
int bytes = System.in.available();
if (bytes > 0) {
System.out.println("Using user entered data ("+size+" bytes)");
} else {
System.out.println("Using default value");
}
} catch(IOException e) { /*handle*/ }
Upvotes: 0
Reputation: 4654
you can use a external flag for this
boolean flag = true;
public void run() {
try {
int n = 0;
byte[] buffer = new byte[4096];
while ((n = in.read(buffer)) != -1 && flag) {
out.write(buffer, 0, n);
out.flush();
}
} catch (IOException e) {
System.out.println(e);
}
}
Upvotes: -3
Reputation: 22646
You could use the available() method (which is non-blocking) to check whether there is anything to read beforehand.
In pseudo-java:
//...
while(running)
{
if(in.available() > 0)
{
n = in.read(buffer);
//do stuff with the buffer
}
else
{
Thread.sleep(500);
}
}
//when running set to false exit gracefully here...
Upvotes: 2
Reputation: 24640
This is because reading System.in (InputStream) is a blocking operation.
Look here Is it possible to read from a InputStream with a timeout?
Upvotes: 8