Java invoke thread inside it's run() - java

I wrote a thread class that checks the socket connection to the server by sending a small string every one second.
begin() method executes the thread.
After connection is lost, the thread tries to connect again.
My question is if it's ok to re-run by begin() the thread inside the run() method like I did (see below).
public void begin() {
Check = new Thread(this);
Check.start();
}
#Override
public void run() {
Thread thisThread = Thread.currentThread();
while (Check==thisThread) {
try {
oos.writeObject("a");
// oos.flush();
synchronized (this) {
while (pleaseWait) {
try {
System.out.println("waiting");
wait();
System.out.println("not waiting");
}
catch (Exception e) {
System.err.println("Thread is interrupted: "+e.getMessage());
}
}
}
sleep(1000);
} catch (Exception ex) {
v = new Visual("The connection is lost. The system will try to reconnect now.");
this.end();
try {
Server=ClientLogin.checkingServers(); //returns the reachable server string address
socket = new Socket(Server, ServerPort);
System.out.println("Connected: " + socket);
oos = new ObjectOutputStream(socket.getOutputStream());
begin();
v = new Visual("The system is reconnected.");
}
catch(UnknownHostException uhe){
System.out.println("Host unknown: " + uhe.getMessage());
v = new Visual("The system has failed to reconnected.");
}
catch (IOException ioe) {
System.out.println("The system cannot connect to servers: " + ioe.getMessage());
v = new Visual("The system has failed to reconnected.");
}
catch (Exception e) {
System.out.println("The system has failed to reconnect: " + e.getMessage());
v = new Visual("The system has failed to reconnected.");
}
}
}
}
public void end() {
Check = null;
}

I don't know any reason why that wouldn't work, but it looks kinda messy. You may have to declare Check as volatile to ensure that the loop always reads the current value, for those times when the new thread overwrites it.
IMHO a better approach would be a separate "supervisor" thread which is responsible for starting one of these threads, and then uses Thread.join() to wait for it to die, at which point it can start it up again.
In this way your main thread's logic can concentrate on exactly what it's supposed to do, without needing to have any "self awareness".

First, the code is not thread safe. The "Check" field is written by one thread but read by another, but it is not synchronised. There is no guarantee that the new started thread is going to see the updated value of "Check", i.e. the new thread will get the old thread's reference when checking "Check==thisThread" and do the wrong thing,
This particular problem can be fixed by making "Check" field volatile. It makes sure when it is updated, every thread will see the new value.
It is not "wrong" to call "begin()" in the run() method. However I wouldn't recommend it because you created a recursive call here effectively. There is a good chance you will get it wrong and fall into infinite loop. Try the simple design below. It uses a while loop instead of recursion.
package com.thinkinginobjects;
public class HeathChecker {
public void run() {
while (true) {
boolean success = checkHeath();
if (!success) {
//log and re-establish connection
} else {
Thread.sleep(1000);
}
}
}
private boolean checkHeath() {
try {
oos.writeObject("a");
return true;
} catch (Exception ex) {
return false;
}
}
}

it is ok, however why do you need to start a thread every time? Isn't it better to use Timer and TimerTask?
http://docs.oracle.com/javase/6/docs/api/java/util/TimerTask.html
http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html

Related

Java 8: Kill/Stop a thread after certain period of time

I have a java 8 based project which performs a certain function on a url. I need to modify the code snippet below so that it is capable of killing the thread/process running and run the next instance after a certain period of time irrespective of current process status.
I tried the following techniques to implement the thread kill procedure:
Executor service
Timer Task
Multithreaded thread kill
The code snippet for my most recent attempt is linked below.
#SuppressWarnings("static-access")
public static void main(String[] args) {
//fetch url from the txt file
List<String> careerUrls = getCareerUrls();
int a = 0;
DBConnection ds = null;
ds = DBConnection.getInstance();
try (java.sql.Connection con = ds.getConnection()) {
//read a single Url
for (String url : careerUrls) {
int c = a++;
ExecutorService executor = Executors.newFixedThreadPool(3);
Future<?> future = executor.submit(new Runnable() {
#Override
// <-- job processing
public void run() {
long end_time = System.currentTimeMillis() + 10000;
System.out.println("STARTED PROCESSING URL: " + url);
jobareaDeciderSample w = new jobareaDeciderSample();
w.mainSample(url, c, con);
}
});
// <-- reject all further submissions
executor.shutdown();
try {
future.get(120, TimeUnit.SECONDS); // <-- wait 2 Minutes to finish
} catch (InterruptedException e) { // <-- possible error cases
System.out.println("job was interrupted");
future.cancel(true);
Thread.currentThread().interrupt();
;
} catch (ExecutionException e) {
System.out.println("caught exception: " + e.getCause());
} catch (TimeoutException e) {
System.out.println("timeout");
future.cancel(true);
}
// wait all unfinished tasks for 2 sec
if (!executor.awaitTermination(0, TimeUnit.SECONDS)) {
// force them to quit by interrupting
executor.shutdownNow();
}
}
} catch (Exception e) {
LOGGER.error(e);
}
}
You are correct with your approach.
calling cancel(true); on future is the right way to stop this task.
You have another problem- you cannot just stop a thread. (well you can, using stop() in thread class, but you should never do this).
cancel(true); sends information to the thread, that it should be stopped. Some java classes are responding to this information and throw interrupted exception. But some dont. You have to modify your task code, to check if Thread.currentThread().isInterrupted(), and if so, stop execution.
This is something you have to do in your code, which you call by
jobareaDeciderSample w = new jobareaDeciderSample();
w.mainSample(url, c, con);
You should do this in some long time spinning code, if you said you do some stuff with url, you should do it in your while loop, where you download information for the web. In other words, do this check only when your code spends 99% of the time.
Also you are calling
Thread.currentThread().interrupt();
in your main thread, this does not do anything for you, as if you want to quit current thread, you can just call return

Ping a server without freezing the Thread

I tried to use multiple threads, sadly no luck:
public synchronized boolean pingServer(final String ip, final short port) {
final boolean[] returnbol = new boolean[1];
Thread tt = new Thread(new Runnable() {
#Override
public void run() {
try {
Socket s = new Socket(ip, port);
s.close();
returnbol[0] = true;
} catch (IOException e) {
returnbol[0] = false;
}
}
});
tt.start();
try {
tt.join();
} catch (InterruptedException e) {
tt.stop();
}
tt.stop();
return returnbol[0];
}
The main thread still Freezes for some reason.
Is there a "lagless" way to ping a server?
What exactly did you want to got in
try {
tt.join();
} catch (InterruptedException e) {
tt.stop();
}
block?
Here you joined to parallel thread and waits till this thread will ends (got ping result).
You have next options:
Wait till ping ends
Don't wait... and don't got result
Use some concurrency classes like Future<> to got result (but you will block thread at moment you ask result if it not retrieved yet)
Or you can use some 'callback' function/interface to threw result from inner 'ping' thread.
You will need to remove the following lines from your code.
The tt.join() will force the main thread to wait for tt to finish.
try {
tt.join();
} catch (InterruptedException e) {
tt.stop();
}
tt.stop();
Use a Future instead to get the result for later use

How to interrupt a task in progress with a timeout mechanism?

I'm currently developping a ftp client based on the package commons.net, in order to run tests to see the speed of the connection.
Basically my ftp test consists in connect to the server, logging onto it, and then start a cycle of download/upload as long as necessary, until the user decides to stop it via a button, then the current cycle will end and so will the test.
However, while running those tests, a situation requiering a timout mechanism has occured. the server was transmitting the file, and send the return code 226 (transfer complete) before it was indeed completed.
So my thread remains stuck, trying to empty the inputStream when it is not possible anymore.
My idea was to start a threaded timer with the downloading process, that will be reset each time a byte is transferred to my client.
When the timeout occurs, then an exception or so would be raised, and my client would react to it, abording the download.
I have read and try many solutions, among them:
- raising an exception from a thread -> the thread catches the exception and not the client;
- interrupt the client from the thread, so the client raises itself an interruptedException -> doesn't seem to work;
- using an executor with a timeout -> since I can't know the "normal" duration of a download, I can't give it to the executor when I start the task, moreover, the timer has to be reset when I receive data.
I read a lot about it on many forums, and didn't find any solution that seem to be adapted AND work in this case. If anyone has an idea of another way to do it?
This is the code of the action I am performing:
public double get(String fileName) {
[...]
org.apache.commons.net.io.Util.copyStream(stO,stD,client.getBufferSize(),
this.localSize,
new org.apache.commons.net.io.CopyStreamAdapter() {
public void bytesTransferred(long totalBytesTransferred,
int bytesTransferred,long streamSize) {
setProgressDL(totalBytesTransferred);
//reset the timer here
}
});
[...]
}
Here is some of the code of my test, launching my client:
public class TestFtp extends Thread {
[...]
public void run() {
System.out.println("Launching FTP test");
FtpClient client = new FtpClient(this.model, this, this.model.getFtpServer());
try {
//Attempting connection on the server
client.connect();
try {
// Attempting login
client.login(this.model.getUsername(), this.model.getPassword());
do {
client.changeDirectory("get");
// start timer
client.get(this.model.getDistantFileName());
// stop timer
client.changeToParentDirectory();
client.changeDirectory("put");
client.set(this.model.getDistantFileName(),
this.model.getNewFileName());
client.changeToParentDirectory();
try {
// Little pause between each test
Thread.sleep(500);
} catch (InterruptedException e) {}
// Continue test until the user stops it
} while (this.continuous);
// Once the test is over, logout
client.logout();
} catch (FTPLoginException e) {
// If login fails, the test ends
System.out.println("Unable to login to the server.");
}
} catch (FTPConnectException e) {
// If connection error, the test ends
System.out.println("Unable to connect to the server.");
}
}
Thank you by advance if anyone can help, and if you need further information on my actual code, I can put more of it in here.
If you do not want to throw unecessary Exceptions, you should use a boolean flag that controls the execution of the thread (or runnable):
public class TestFtp extends Thread {
[...]
boolean abort;
public void run() {
[...]
do{
[...]
} while (this.continuous && !abort);
if (abort){
// You might want to do something here
}else{
// The stuff you normally do
}
}
}
And then simply set the abort flag to false from outside.
This way you can better control how you thread will terminate, as thread.interrupt(); will have an undefined behavior.
Well, I'm sorry but I admit I haven't read all your code, but if you want to interrupt a running thread, do two things:
run the thread code inside a try/catch block like this:
Example:
public void run() {
try {
// code to run
} catch (InterruptedException ie) {
// thread interrupted, may want to do some clean up
// but must return as quickly as possible to avoid halting external code
}
}
Call the interrupt() method of the thread above externally when the need arises.
Example:
thread.interrupt();
This will tell the VM to throw the InterruptedException in your thread no matter what it's doing, giving you a chance to do some stuff.
I hope this is what you're looking for...
EDIT
Ok, a concrete example that works:
public class Driver {
private static int count = 0;
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
bigTask();
} catch (InterruptedException ie) {
System.out.println("Interrupted thread! Count is " + count);
}
}
});
t.start();
try {
Thread.sleep(1000);
System.out.println("Trying to interrupt thread");
t.interrupt();
} catch (InterruptedException e) {}
}
private static void bigTask() throws InterruptedException {
List<BigDecimal> bigs = new ArrayList<BigDecimal>();
for (int i = 0; i < 10000000; i++) {
bigs.add(BigDecimal.valueOf(i));
if (Thread.interrupted()) {
throw new InterruptedException();
}
count = i;
}
System.out.println("Ok, added ten million items, count is " + count);
}
}

Stop() method in a thread?

In the following example how stop() method is implemented??
What should be done instead of using stop() method?
In my point of view ,When the desired state is suspended, the thread waits using Object.wait. When the thread is resumed, the target thread is notified using Object.notify. but doubtful in case of implentation of stop() in the below example.
Class NewThread implements Runnable {
String name; // name of thread
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while(suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming thread One");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
The thread automatically stop if it returns the run() function.no need to use the stop() function because stop method is deprecated by java and unsafe to use
Calling stop method will kill the thread on which it is called. A thread must only be killed when there is no use of continuing what a thread is doing. When you will call the stop method, the Thread will stop its execution and will die.
It is preferable to allow thread to complete its run method and kill itslef rather than killing it forcefully.
Calling stop() triggers an exception/error to be thrown in the thread at a random point. If you have access to all the code for the thread it can be used safely, however if this the case, you are far better off supporting interrupts.
Instead of Object.wait/notify, you are likely to be better off using high level concurrency library support i.e. use a Lock which would simplify your code.
For more on stop(); Does Thread.stop() really stop a Thread?
It depends on your threads and what they have to do really.
If they are workers that for example listen to a tcp/ip socket, then you're better off having a volatile boolean inside of the class that says wether or not the loop inside your run() method should continue. Then have your class that extends thread implement a pleaseStop() function which puts the boolean to false, which then causes your run method to finish gracefully (you can even clean up your resources then).
On the other hand, if they are workers that have a finite amount of work to be done, then you should just wait for them to be ready, using the join() functionality.
private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if (jToggleButton1.isSelected()) {
jToggleButton1.setBackground(Color.green);
jToggleButton1.setText("ON");
//MainClass main = new MainClass();
new Thread(new Runnable() {
#Override
public void run() {
try {
server = new ServerSocket(4400, 500);
do {
socket = server.accept();
ClientHandler cliendHandler = new ClientHandler(socket);
cliendHandler.start();
} while (true);
} catch (IOException ex) {
}
}
}).start();
} else {
try {
server.close();
jToggleButton1.setText("START SERVER");
jToggleButton1.setBackground(Color.red);
} catch (IOException ex) {
Logger.getLogger(Server_Prog.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Why client thread is destroyed after it is executed only once? Java TCP sockets

I want my client class to run a thread that sends String information (order) to the server continuously every 5 sec. But instead thread is destroyed after it sends first order. I dont know why and how to stop it, can somebody help me?
below code;
public class Cashier implements Runnable
{
private static final int MAX_DELAY = 5000;
static OrderList orderList;
static Socket socket;
static PrintWriter out = null;
static BufferedReader in = null;
int orderNumber = 0;
public String order, strorderNumber;
public static void main(String[] args){
Cashier newCashier = new Cashier();
Thread cashierThread = new Thread(newCashier);
cashierThread.setName("Olaf");
cashierThread.setDaemon(false);
cashierThread.start();
try {
socket = new Socket("127.0.0.1", 4444);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run()
{
try{
Date now = new Date();
Format fTime = new SimpleDateFormat("hh:mm:ss a");
order = ("Order made by " + Thread.currentThread().getName()+ " at " + fTime.format(now)+ "\n");
out.print(order);
Random randomNumber = new Random();
Thread.sleep(randomNumber.nextInt(MAX_DELAY));
} catch (InterruptedException exception){
System.out.println("Olafs interrupted exception");
}
}
}
The run method for your class does not contain a loop, so it will do what it has to do once then fall out the bottom, effectively terminating the thread.
If you want it to run continuously, you'll need something like:
public void run() {
boolean keepGoing = true;
while (keepGoing) {
try {
Date now = new Date();
Format fTime = new SimpleDateFormat("hh:mm:ss a");
order = "Order made by " + Thread.currentThread().getName()
+ " at " + fTime.format(now)+ "\n";
out.print(order);
Random randomNumber = new Random();
Thread.sleep(randomNumber.nextInt(MAX_DELAY));
} catch (InterruptedException exception){
System.out.println("Olafs interrupted exception");
keepGoing = false;
}
}
}
#paxdiablo has given you a solution to your problem. The answer to your "why" question is in the way that the Thread API works; specifically the Thread.start() method. The javadoc says this:
public void start()
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
This says that a Thread is started by calling the start method, which calls the thread's run method once. This in turn calls the run method of the Runnable that you supplied as a constructor argument ... once. (If you were to extend the Thread class, and override the Thread.run() method, this second step would typically not happen. But that's a side issue.)
When the Runnable.run() method returns, the Thread.run() method returns and that is it. The thread terminates, its stack is blown away, and you cannot start it again. All you can do is to examine what little remains of the thread state via the Thread object.
Hmm.. there's no loop what-so-ever to perform the 5min interval operation, or am I missing something?

Categories