I have the problem, that the join Method, to kill a thread, is not executing the rest of the method, which was started also in the thread. Here is a code example:
private static Thread thread;
public static void addMessage(final String s) {
thread = new Thread() {
#Override
public void run() {
String data = Message.send(s);
addMessageToContainer(data);
}
};
thread.start();
}
public static void addMessageToContainer(String data) {
//Do some stuff with the data
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//This code here will not be executed.
}
So normally, of course I can execute the code before I call the join function. But I have to load after this thread execution a webview with some content. So when I do remove the join, it will give me the following error message:
java.lang.RuntimeException: java.lang.Throwable: A WebView method was called on thread 'Thread-9072'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {5ac9b39} called on null, FYI main Looper is Looper (main, tid 1) {5ac9b39})
So what can I do to load the content after the thread has executed?
Join doesn't kill a thread. Join waits until that thread kills itself. So that code would be executed- just at some time in the future, when that thread decides its done. Calling wait on a thread from that thread will cause it to deadlock and never do anything, yet never die. So in the case above where you're calling it from the thread itself, it will just hang forever.
There is no way to kill a thread directly, because its impossible to do so safely. The way to kill a thread from the outside is to interrupt it, and let the thread check if it isInterrupted() every so often and if so kill itself. The way to kill a thread from the inside is to return from the runnable's run method.
Your webview error is totally unrelated. You can only touch views on the main thread. Don't do anything with a webview on a thread.
Related
I have code that schedules one-time tasks to execute and does this over and over. It looks something like this.
public static void main(String[] args)
{
while(true)
{
....
TimerTask closeTask = new CloseTask(cli);
Timer timer = new Timer(true);
timer.schedule(closeTask, (long) (iPeriod * 60 * 1000));
...
}
}
public class CloseTask extends TimerTask
{
Client client;
CloseTask(Client in_client)
{
client = in_client;
}
public void run()
{
try
{
for(int iRetries = 0; state == OPEN; iRetries++)
{
logger.log_trade_line_grablock( "Thread " + Thread.currentThread().getId() + ": About to send message", true, true, true, true, true);
client.send_mesg("close");
logger.log_trade_line_grablock( "Waiting 5 seconds before retrying ", true, true, true, true, true);
Thread.sleep(5000);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
The intent of the run() method in the CloseTask class is to loop until the state variable changes from OPEN state to something else. However, intermittently the timer threads simply disappear, while state still equals OPEN, which I know by printing out all the thread ID's of the currently running threads every 5 minutes.
So my questions:
1) The only explanation I can think of is that the CloseTask object is throwing uncaught exceptions. Is that correct?
2) If 1) is correct why isn't my try catch block catching these exceptions?
3) If 1) is correct is there a way to catch these exception that slip through uncaught?
Thanks for any insight into this issue.
You're creating a Timer instance, but not making sure that it doesn't get garbage collected.
From the documentation:
After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection).
So basically, you need to hold on to the reference to the Timer you created instead of just using a local variable.
The boolean you are passing in tells whether or not the thread created will be daemon. If it is daemon, the thread will be stopped once all non-daemon threads are finished. Since the only non-daemon thread being run in your application is the main thread then it will immediately be stopped after the main method is completed.
As Jon Skeet mentioned there is some completion operations done if no live thread is referencing the Timer and the tasks complete, but if it's daemon and the main method completes, it may not exit gracefully. To continue the documentation
... However, this can take arbitrarily long to occur. By default, the task execution thread does not run as a daemon thread, so it is capable of keeping an application from terminating. If a caller wants to terminate a timer's task execution thread rapidly, the caller should invoke the timer's cancel method.
To answer your question
The only explanation I can think of is that the CloseTask object is throwing uncaught exceptions. Is that correct?
If the JVM kills a non-daemon thread, it won't throw any exception. So you won't really know that it happened.
I am developing a module inside my system where based on some event the user has to receive sms.
I have the following situation
synchronized(notificationPhoneNumber)
{
SmsProvider.sendSms(notificationPhoneNumber, smsText);
}
The code of the method sendSms is running asynchronious:
public static void send(final NotificationPhoneNumber npn, final String smsText)
{
Thread smsSender = new Thread(new Runnable()
{
public void run()
{
//sms sending code runs here....
}
});
smsSender.start();
}
So the question is how long is the notificationPhoneNumber object locked in this case? Is it going to be locked by the time the thread finishes its job or not?
As long as
SmsProvider.sendSms(notificationPhoneNumber, smsText);
doesn't return. That means, your sendsms() method will create a thread and return. Just for that amount of time.
Also, if you start your thread in your method. The created thread will just hold the reference but not the lock after sendsms() returns.
The lock and synchronization are external to sendsms(). Whichever thread calls sendsms()
will acquire the lock and the code within sendsms() has no knowledge of it.
synchronized(notificationPhoneNumber){
...
}
Here NotificationPhoneNumber object will be locked untill synchronized block executed and once it is execution is over, Thread will release the lock of that Object.
A synchronized statement acquires a mutual-exclusion lock (§17.1) on
behalf of the executing thread, executes a block, then releases the
lock. While the executing thread owns the lock, no other thread may
acquire the lock.
read more on documentation
I'm getting some exception and I need to know when the program closes itself because I need to close the socket.
I have the default public static main method where I'm keep repeating an action and a Thread class.
private static Thread thread;
public static boolean isRunning = true;
public static void main(String[] args){
thread = new Thread(new ThreadListenServer());
thread.start();
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run(){
// some action
}
}
timer.scheduleAtFixedRate(task, 0, 10000);
isRunning = false;
}
And the thread class which is running in background:
public class ThreadListenServer implements Runnable{
private DatagramSocket socket;
public ThreadListenServer() throws SocketException{
socket = new DatagramSocket(6655);
}
#Override
public void run() {
while(MainProgram.isRunning){
// some action
}
socket.close();
}
}
I don't know why, but isRunning it's becoming false, but it shouldn't. How am I supposed to close the socket if the main program was closed? (It's causing because the Thread still running in the background even if the program was closed).
I was thinking about to create the socket in the main class then I pass the socket object as a parameter to the ThreadClass and if the program is closed, than I should close the socket as well.
Use:
thread.setDaemon(true);
This will shut the thread. It tells the JVM it is a background thread , so it will shut down on exit.
Ill take the assumption you have a JFrame of some sort running as the class MainProgram. You have 2 options
1: set your Jframe to close all threads when it is closed.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
2: add a window listener and manually close your thread (maybe you have to send some information across the socket before you close it)
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// send your socket its close message and shut everything down
System.exit(0);
}
});
To stop all Threads when your program exits cleanly, you'll need to define a termination policy for each Thread that gets started. This is normally done using Interrupts and ExecutorService.shutdownNow() method sends an interrupt to each running thread.
A clean termination policy consists to two parts:
Sending stop signal to thread – aka interrupting it
Designing threads to act on interruption
A thread in Java could be interrupted by calling Thread.interrupt() method. Threads can check for interruption by calling Thread.isInterrupted() method. A good thread must check for interruption at regular intervals, e.g. as a loop condition and checking blocking functions for InterruptedExceptions.
It is important to note that Sockets in Java are oblivious to interruption. For example, if a Thread is blocked on Socket.accept(), it will not throw InterruptedException when the Thread is interrupted. In this case, you need to define a public method which closes the underlying socket by calling Socket.close() forcing the blocking function to throw an Exception (I guess SocketException).
A few things come to mind.
It would appear you are performing a blocking I/O operation using sockets. You may need to interrupt either the running thread and/or the socket to get it to stop blocking
You should set the thread as daemon thread before it is started, using setDaemon(true). This will allow the JVM to terminate the thread automatically...
isRunning should be marked volatile or you should use AtomicBoolean instead
Hello i am having a problem with resuming a thread my code is
public boolean Wait(String Reply){
if (Reply.equalsIgnoreCase("Y")){
try {
t.resume();
}
catch (Exception e){
System.out.println("\n" + "The exception in resume thread method:::: " + e);
}
System.out.println("\n" + "In the Wait Function of Sender");
return true;
}
JOptionPane.showMessageDialog(j ,
"Please Wait While The User Accpets the Trasmission ",
"",
JOptionPane.INFORMATION_MESSAGE);
try{
t = new Thread(this);
t.sleep(100000);
}
catch (InterruptedException ie){
System.out.println(ie.getMessage());
}
return false;
}
I might explain you how it works as it will help u determine the problem.
First the thread is put to sleep......Then i call this public boolean Wait() function from another function named ReplyYes which passes the value "Y" and i then try to resume the thread but the t.resume() function call, instead of resuming the thread gives me a Java.Lang.Null.PointerException and the thread isn't resumed resulting in returning a FALSE value. Plus because of this thread i can't even Stop my Service i have to wait for the thread to timeOut.
Can anyone explain how to make it work correctly!!
Thank you
I think you misunderstand how Thread.sleep works. It is a static method.
The line t.sleep(100000); puts the current thread to sleep, not the thread t.
From the documentation:
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds
Emphasis mine.
You should start the thread and call sleep from that thread. See the following article for two different ways to start a thread:
Defining and Starting a Thread
Furthermore, resume is only for use with suspend and they have both been deprecated. From the documentation:
Deprecated. This method exists solely for use with suspend(), which has been deprecated because it is deadlock-prone. For more information, see Why Are Thread.stop, Thread.suspend,
Thread.resume and Runtime.runFinalizersOnExit Deprecated?
The reason you get a NullPointerException is probably because you try to create the new Thread object after you call t.resume(). So at that point, t still has the value null. Basically, your code needs to be completely rewritten from scratch. I would suggest following the tutorial I linked to above, then once you understand how to create threads move to the next chapters:
Pausing Execution with Sleep
Interrupts
at first you must start new Thread: t.start(); then try to wake up your thread: t.interrupt();
Call Thread.sleep() inside your run() method, this causes to sleep thread that calls this method
in my class I have an inline thread in the constructor that loads objects from a remote site:
Thread readSite = new Thread(new Runnable() {
public void run() {
site.loadStuff();
}
});
readSite.start();
I want to display a 'loading' message until the thread is finished. So before the above code I show a loading message.
After the above code I show the screen in which I would like to continue.
The code looks like this:
showLoadingView(); //tells the user it is waiting
Thread readSite = new Thread(new Runnable() {
public void run() {
site.loadStuff();
}
});
readSite.start();
showStuffView(); //works with the data retrieved from the site instance
Now, the main thread of course continues and the showStuffView() is directly executed.
I can now let the main thread wait for the readSite Thread, but then the user cannot accept the connection request ('is it ok to use airtime?') that is shown to the user (because the responsible thread is asleep I guess).
On the other side, I cannot execute the showStuffView() from the readSite Thread.
I hope you guys can explain how to wait for this thread. I looked into synchronized, but couldn't really find a nice solution.
I think this is a common problem with threads and this particular problem you can solver with boolean variable. but for general purpose i think observer pattern is good.