Edit: I know what Thread.interrupt() does.
while (!Thread.currentThread().isInterrupted()) does not exit when I interrupt the thread.
I also tried to catch an exception from url.openStream(); when the
thread is interrupted (desperation, maybe it was a blocking method,
which is not) and exit the loop, without any success.
The application creates a Thread that continuously reads a URL. After 3 seconds that Thread gets interrupted but unfortunately continues to execute.
How to stop the thread from executing?
Code (Main.java, MyRunnable.java):
public class Main {
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable("http://ninjaflex.com/");
Thread thread = new Thread(runnable);
thread.start();
sleep(3000);
thread.interrupt();
System.out.println("Thread.interrupt() invoked.");
}
private static void sleep(long timeMilli) {
try {
Thread.sleep(timeMilli);
} catch (Exception e) {
}
}
}
public class MyRunnable implements Runnable {
private String website;
MyRunnable(String website) {
this.website = website;
}
#Override
public void run() {
URL url = createUrl();
if (url != null) {
while (!Thread.currentThread().isInterrupted()) {
sleepOneSec();
readFromUrl(url);
System.out.println("Read from " + website);
}
System.out.println("Script: Interrupted, exiting.");
}
}
private URL createUrl() {
URL url = null;
try {
url = new URL(website);
} catch (MalformedURLException e) {
System.out.println("Wrong URL?");
}
return url;
}
private void sleepOneSec() {
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("Error sleeping");
}
}
private void readFromUrl(URL url) {
InputStream in = null;
try {
in = url.openStream();
} catch (Exception e) {
System.out.println("Exception while url.openStream().");
e.printStackTrace();
} finally {
closeInputStream(in);
}
}
private void closeInputStream(InputStream in) {
try {
in.close();
} catch (IOException e) {
System.out.println("Error while closing the input stream.");
}
}
}
Basically, your MyRunnable thread is interrupted during sleep. InterreuptedException is thrown but catched. By the way, it's a bad habit to catch Exception and you should not do that.
From the javadoc: "The interrupted status of the current thread is cleared when this exception is thrown".
Therefore, your while loop will never see the flag.
Replace the call to the sleepOneSec method with a simple Thread.sleep call. Catch InterruptedException outside your while loop. This will cause the loop to exit naturally:
try {
while (true) {
Thread.sleep(1000);
readFromUrl(url);
System.out.println("Read from " + website);
}
} catch (InterruptedException e) {
System.out.println("Script: Interrupted, exiting.");
}
I removed the MyRunnable.sleepOneSec and your code started to work.
Related
In my android app I need to send Data between two apps. When the GameClient get initialized, it will start three Threads.
The first one will create a Socket and the ReceivingThread. I need to do it in a Thread, because Android won't let me do network connection on MainThread:
new Thread(new Runnable() {
#Override
public void run() {
try {
if (mSocket == null) {
setSocket(new Socket(mAddress, mPort));
Log.d(TAG, "Client-Socket set.");
} else {
Log.d(TAG, "Socket already set. Skip.");
}
mRecCardThread = new ReceivingCardThread();
mRecCardThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
mSendCardThread = new SendingCardThread();
mSendCardThread.start();
After that I create the third Thread for Sending data.
The problem occurs when I connect to another phone and immediately want to send some Data.
mConnection.connectToServer(d.getHost(), d.getPort());
mConnection.sendCard(new int[]{0, 0, 0});
My Sending Thread tries to Send data, but will often be called earlier than the setSocket method.
private synchronized void setSocket(Socket socket) {
Log.d(TAG, "setSocket called");
if (mSocket != null) {
if (mSocket.isConnected()) {
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
mSocket = socket;
if (mClient != null)
mClient.mSendCardThread.notifyAll();
Log.d(TAG, "Notify all, that Socket is set");
}
private class SendingCardThread extends Thread {
BlockingQueue<int[]> mCardQueue = new ArrayBlockingQueue<>(10);
private ObjectOutputStream mOutput;
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
int[] nums = mCardQueue.take();
sendCard(nums);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private synchronized void sendCard(int[] nums) {
try {
if (mOutput == null) {
while (mSocket == null) {
Log.d(TAG, "Waiting for Socket to be set.");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "Not waiting anymore.");
}
mOutput = new ObjectOutputStream(mSocket.getOutputStream());
}
mOutput.writeObject(nums);
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, "Client send:" + Arrays.toString(nums));
}
}
So I thought about to let the sending-Thread wait when the Socket is still null and when the Socket is created wakeing up the sending-Thread to be sure that the Socket is not null at the beginning.
But this will cause a IllegalMonitorStateException: object not locked by thread before notifyAll().
So it seems like it tries to notify but the Sending Thread isn't waiting. But I don't know how to solve this problem. I think also that I don't understand how to use wait() and notify() in praxice.
I hope one of you guys can help me to solve this stupid problem ;D
I am working on a java application in which I am facing a problem. When I send a file to a server and an exception is thrown, the file is not sent. How can I retry sending the file?
public void uploadtxtFile(String localFileFullName, String fileName, String hostDir)
throws Exception {
File file = new File(localFileFullName);
if (!(file.isDirectory())) {
if (file.exists()) {
FileInputStream input = null;
try {
input = new FileInputStream(new File(localFileFullName));
if (input != null) {
hostDir = hostDir.replaceAll("//", "/");
logger.info("uploading host dir : " + hostDir);
//new
// TestThread testThread=new TestThread(hostDir,input);
// Thread t=new Thread(testThread);
//
// try{
// t.start();
//
// }catch(Exception ex){
// logger.error("UPLOADE start thread create exception new:" + ex);
// }
// // new end
DBConnection.getFTPConnection().enterLocalPassiveMode();
// the below line exeption is come
boolean bool = DBConnection.getFTPConnection().storeFile(hostDir, input);
//input.close();//new comment
if (bool) {
logger.info("Success uploading file on host dir :"+hostDir);
} else {
logger.error("file not uploaded.");
}
} else {
logger.error("uploading file input null.");
}
}catch(CopyStreamException cs)
{ logger.error("Copy StreamExeption is come "+cs);
} catch(Exception ex)
{
logger.error("Error in connection ="+ex);//this is catch where I handle the exeption
}finally {
// boolean disconnect= DBConnection.disConnect();
input.close();
}
} else {
logger.info("uploading file is not exists.");
}
}
}
This is the code and I want to restart the file uploading but I don't have any idea. I tried it using the thread but the exception is thrown again. I also tried to use a while loop, but it loops infinitely and also shows the exception as well as another exception.
Below is the thread code that I use:
public void run() {
System.out.println("Enter Thread TestThread");
DBConnection.getFTPConnection().enterLocalPassiveMode();
// System.out.println("Error in DBConnection ");
//here server timeout error is get
boolean bool1=false;
boolean bool=true;
try {
bool = DBConnection.getFTPConnection().storeFile(hostDir1, input1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//disconnect();
try {
input1.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (bool) {
System.out.println("File is Uploded");
} else {
while(bool!=true){
try {
DBConnection.getFTPConnection().enterLocalPassiveMode();
bool1=DBConnection.getFTPConnection().storeFile(hostDir1, input1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//disconnect();
try {
input1.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("file not uploaded."+bool1);
bool=bool1;
}
}
}
}
}
Can any one have a solution to how to upload the file to the server?
The exception is shown below:
Software caused connection abort: recv failed
Software caused connection abort: socket write error
org.apache.commons.net.io.CopyStreamException: IOException caught while copying.
Add a static class as below in a class from where you are calling the method which need to be retried:
static class RetryOnExceptionStrategy {
public static final int DEFAULT_RETRIES = 3;
public static final long DEFAULT_WAIT_TIME_IN_MILLI = 2000;
private int numberOfRetries;
private int numberOfTriesLeft;
private long timeToWait;
public RetryOnExceptionStrategy() {
this(DEFAULT_RETRIES, DEFAULT_WAIT_TIME_IN_MILLI);
}
public RetryOnExceptionStrategy(int numberOfRetries,
long timeToWait) {
this.numberOfRetries = numberOfRetries;
numberOfTriesLeft = numberOfRetries;
this.timeToWait = timeToWait;
}
/**
* #return true if there are tries left
*/
public boolean shouldRetry() {
return numberOfTriesLeft > 0;
}
public void errorOccured() throws Exception {
numberOfTriesLeft--;
if (!shouldRetry()) {
throw new Exception("Retry Failed: Total " + numberOfRetries
+ " attempts made at interval " + getTimeToWait()
+ "ms");
}
waitUntilNextTry();
}
public long getTimeToWait() {
return timeToWait;
}
private void waitUntilNextTry() {
try {
Thread.sleep(getTimeToWait());
} catch (InterruptedException ignored) {
}
}
}
Now wrap your method call as below in a while loop :
RetryOnExceptionStrategy errorStrategy=new RetryOnExceptionStrategy();
while(errorStrategy.shouldRetry()){
try{
//Method Call
}
catch(Exception excep){
errorStrategy.errorOccured();
}
}
Basically you are just wrapping you method call in while loop which will
keep returnig true till your retry count is reached to zero say you started with 3.
Every time an exception occurred, the exception is caught and a method is called
which will decrement your retryCount and method call is again executed with some delay.
A general way of working with such application is:
Create a class, say, UploadWorker which extends Callable as the wrapper. Make the wrapper return any error and detail information you need when it fails.
Create a ExecutorService (basically a thread pool) for this wrapper to run in threads.
Submit your UploadWorker instance and then you get a Future. Call get() on the future to wait in blocking way or simply wait some time for the result.
In case the get() returns you the error message, submit your worker again to the thread pool.
I am using an actionListener to trigger an sequence of events and ultimatley this code is called:
public class ScriptManager {
public static Class currentScript;
private Object ScriptInstance;
public int State = 0;
// 0 = Not Running
// 1 = Running
// 2 = Paused
private Thread thread = new Thread() {
public void run() {
try {
currentScript.getMethod("run").invoke(ScriptInstance);
} catch(Exception e) {
e.printStackTrace();
}
}
};
public void runScript() {
try {
ScriptInstance = currentScript.newInstance();
new Thread(thread).start();
State = 1;
MainFrame.onPause();
} catch (Exception e) {
e.printStackTrace();
}
}
public void pauseScript() {
try {
thread.wait();
System.out.println("paused");
State = 2;
MainFrame.onPause();
} catch (Exception e) {
e.printStackTrace();
}
}
public void resumeScript() {
try {
thread.notify();
System.out.println("resumed");
State = 1;
MainFrame.onResume();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopScript() {
try {
thread.interrupt();
thread.join();
System.out.println("stopped");
State = 0;
MainFrame.onStop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The runnable is created and ran, however, the problem occurs when I try to use the any of the other methods, they lock my UI. (I'm assuming this is because im running this on the EDT) Does anyone know how to fix this?
That's not how you use wait and notify. They need to be executed on the thread that you are trying to pause and resume. Which means you need to send a message to the other thread somehow. There are various ways to do this, but the other thread needs to be listening for this message, or at least check for it occassionally.
In a java class I have a method that sometimes takes a long time for execution. Maybe it hangs in that method flow. What I want is if the method doesn't complete in specific time, the program should exit from that method and continue with the rest of flow.
Please let me know is there any way to handle this situation.
You must use threads in order to achieve this. Threads are not harmful :) Example below run a piece of code for 10 seconds and then ends it.
public class Test {
public static void main(String args[])
throws InterruptedException {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("0");
method();
}
});
thread.start();
long endTimeMillis = System.currentTimeMillis() + 10000;
while (thread.isAlive()) {
if (System.currentTimeMillis() > endTimeMillis) {
System.out.println("1");
break;
}
try {
System.out.println("2");
Thread.sleep(500);
}
catch (InterruptedException t) {}
}
}
static void method() {
long endTimeMillis = System.currentTimeMillis() + 10000;
while (true) {
// method logic
System.out.println("3");
if (System.currentTimeMillis() > endTimeMillis) {
// do some clean-up
System.out.println("4");
return;
}
}
}
}
Execute the method in a different thread, you can end a thread at anytime.
Based on the above snipplet, I tried creating a glorified spring bean.
Such executor runs the passed limitedRuntimeTask in limited runtimeInMs.
If the task finishes within its time limits, the caller continues normally in execution.
If the limitedRuntimeTask fails to finish in the defined runtimeInMs,
the caller will receive the thread execution back. If a timeBreachedTask was defined,
it will be executed before returning to caller.
public class LimitedRuntimeExecutorImpl {
public void runTaskInLessThanGivenMs(int runtimeInMs, final Callable limitedRuntimeTask, final Callable timeBreachedTask) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
LOGGER.info("Started limitedRuntimeTask");
limitedRuntimeTask.call();
LOGGER.info("Finished limitedRuntimeTask in time");
} catch (Exception e) {
LOGGER.error("LimitedRuntimeTask exception", e);
}
}
});
thread.start();
long endTimeMillis = System.currentTimeMillis() + runtimeInMs;
while (thread.isAlive()) {
if (System.currentTimeMillis() > endTimeMillis) {
LOGGER.warn("LmitedRuntimeTask did not finish in time (" + runtimeInMs + ")ms. It will run in vain.");
if(timeBreachedTask != null ){
try {
LOGGER.info("Executing timeBreachedTask");
timeBreachedTask.call();
LOGGER.info("Finished timeBreachedTask");
} catch (Exception e) {
LOGGER.error("timeBreachedTask exception", e);
}
}
return;
}
try {
Thread.sleep(10);
}
catch (InterruptedException t) {}
}
}
}
I feel the approach in accepted answer is a bit outdated. With Java8, it can be done much simpler.
Say, you have a method
MyResult conjureResult(String param) throws MyException { ... }
then you can do this (keep reading, this is just to show the approach):
private final ExecutorService timeoutExecutorService = Executors.newSingleThreadExecutor();
MyResult conjureResultWithTimeout(String param, int timeoutMs) throws Exception {
Future<MyResult> future = timeoutExecutorService.submit(() -> conjureResult(param));
return future.get(timeoutMs, TimeUnit.MILLISECONDS);
}
of course, throwing Exception is bad, here is the correct extended version with proper error processing, but I suggest you examine it carefully, your may want to do some things differently (logging, returning timeout in extended result etc.):
private final ExecutorService timeoutExecutorService = Executors.newSingleThreadExecutor();
MyResult conjureResultWithTimeout(String param, int timeoutMs) throws MyException {
Future<MyResult> future = timeoutExecutorService.submit(() -> conjureResult(param));
try {
return future.get(timeoutMs, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
//something interrupted, probably your service is shutting down
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} catch (ExecutionException e) {
//error happened while executing conjureResult() - handle it
if (e.getCause() instanceof MyException) {
throw (MyException)e.getCause();
} else {
throw new RuntimeException(e);
}
} catch (TimeoutException e) {
//timeout expired, you may want to do something else here
throw new RuntimeException(e);
}
}
I have a server in Java which is multithreading, and I've created a thread pool for it.
Now everything goes well and my server accepts and reads data from the clients that connect to it, but I don't know really how to clean up the sockets after the connections are closed.
So here is my code:
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ThreadPooledServer server = new ThreadPooledServer(queue,7001);
new Thread(server).start();
}
ThreadPooledServer class:
public class ThreadPooledServer implements Runnable {
protected ExecutorService threadPool = Executors.newFixedThreadPool(5);
public ThreadPooledServer(BlockingQueue queue,int port) {
this.serverPort = port;
this.queue=queue;
}
public void run() {
openServerSocket();
while (!isStopped()) {
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
clientconnection++;
} catch (IOException e) {
if (isStopped()) {
System.out.println("Server Stopped.");
return;
}
throw new RuntimeException("Error accepting client connection", e);
}
WorkerRunnable workerRunnable = new WorkerRunnable(queue,clientSocket);
this.threadPool.execute(workerRunnable);
}
this.threadPool.shutdown();
System.out.println("Server Stopped.");
}
private synchronized boolean isStopped() {
return this.isStopped;
}
public synchronized void stop() {
this.isStopped = true;
try {
this.serverSocket.close();
}
catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
Here's what I don't understand: My while() loop that accepts for clients works as loong as isStopped is false.
When isStopped is set to true, my loop ends and then I shut down my thread pool, which is correct.
isStopped is set to true in onstop(){..............}....
Where should I call onstop()...?
Because in this moment I'm not using this method ,I'm not calling it and that means that I'm not cleaning correctly my threads.
WorkerRunnable class:
public class WorkerRunnable implements Runnable {
public WorkerRunnable(BlockingQueue queue2, Socket clientSocket2) {
// TODO Auto-generated constructor stub
this.clientSocket2 = clientSocket2;
this.queue2 = queue2;
}
public void run() {
try {
is = new ObjectInputStream(this.clientSocket2.getInputStream());
try {
while (!stop) {
System.out.println("Suntem in interiorul buclei while:!");
v = (Coordinate) is.readObject();
queue2.put(v);
}
} catch (Exception e) {
e.printStackTrace();
is.close();
clientSocket2.close();
}
is.close();
clientSocket2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void stop() {
this.stop = true;
}
}
}
Here I have the same issue. How should I clean and close up my sockets correctly?
Once you call shutdown() the thread pool will close off each thread once all the tasks are complete.
You should call onstop() from whatever code knows the pool should be shutdown. This depends on what the rest of your application does and why you would stop the pool before the application has finished.