Java threads executing then being interupted multiple times - java

I am having a strange issue where I have a thread being used to listen for incoming messages on a socket. The thread is declared globally but instantiated inside method listen(). This allows me to interrupt it from another method stopListen() which works perfectly the first time, however when listen() and stopListen() are called a second time it does not appear to get interrupted. The code commented as "Do some stuff" still executes after waiting for the incoming message the second time. Below is a cut down version of the code.
public class Con {
private Thread listen;
public void listen() {
listen = new Thread(new Runnable() {
#Override
public void run() {
while (!Thread.interrupted()) {
//Wait for an incoming message
if (!Thread.interrupted()){
//Do some stuff
}
}
}
});
listen.start();
}
public void stopListen() {
listen.interrupt();
}
}
I understand its a bit weird having a variable and a method called the same thing. Should this work or can I not interrupt threads by using a global variable more than once?
Thanks.

The main problem I see is that interrupted() will reset the interrupt-flag (see linked doc), meaning the next call to interrupted() will return false unless it has been interrupted again. Instead, use isInterrupted() which does not clear the flag!
Also, as chr said, if you start multiple threads (calling listen() multiple times) you will only be able to interrupt the latest one. In that case, make a List of Threads and interrupt them all (or only the first one in the list and remove it from the list, or whatever functionality you want).

Related

How do I create methods for a thread?

I'm writing an android application.
In the main thread, it is possible to define methods and then call the methods, which helps keep the code clean. In a new thread, how does one define methods, to avoid writing all the code in "one block"? Is it possible to call methods defined in the main thread, or can you define them inside the new thread somehow?
So to be clear, what I want to do is this:
volatile Runnable feedToBuffer = new Runnable()
{
#Override
public synchronized void run()
{
if(boolean)
{
MethodA();
}
else
{
MethodB();
}
}
and not this:
volatile Runnable feedToBuffer = new Runnable()
{
#Override
public synchronized void run()
{
if(boolean)
{
//Code that was in MethodA
}
else
{
//Code that was in MethodB
}
}
}
Is that possible?
I realize this info is probably out there somewhere, but haven't found it, so really grateful for any help. :)
It's perfectly possible. Thread is just a sequence of actions, and if it involves a method call, it will be executed within that sequence. It doesn't matter.
Threads are in no way tied to the structure of your code. The main difference between the threads you start and the one you have already when the app starts is the points of entry. When Android starts the main thread, it enters your app in many points, in the activity that would be the lifecycle calls like onCreate() or button click listeners. When you create a new thread, your point of entry is the run method from where you can call anything you want.
There is also a difference in that the main thread runs an event loop. Basically, there is a queue of messages that it has to process. Each time something arrives to the queue, it processes the message, then goes back to waiting. In that sense the main thread never ends. Your thread, however, stops when it reaches the end of the run method. Of course, you can implement a similar event loop for your thread yourself.
Other than that there are no fundamental differences in how the threads operate, you can call methods from any thread freely. Of course, there are rules of multithreading like avoiding blocking the main thread, synchronization, and so on, but it's too much to cover in one answer.

Java Method Call from Thread

If I have a game that has a thread for each client, maintaining information about that client, and a thread for the server that maintains information about the game world, would calling a method on the main server thread from one of the client threads run that method on the client thread, or the server thread?
Threads are like the literal meaning of the word a string of commands. A computer has a single instruction pointer per thread to keep track where in the code the thread currently is. If you call a method, the program execution jumps there, and back once the method has finished. But it's not going to leave the thread. Code executing in a thread can never jump to a different thread.
The only way you can have your code execute in a different thread is to make the other thread call it for you.
But since you can't call the other thread directly, how can you make it call a method for you? Basically, program the other thread to wait for changes in a variable, and once it sees that variable change it can call the method.
So cross thread method invocation is actually communication through shared memory and it only works with special threads that are programmed to look at the shared memory. You can't execute code in Threads that just blindly do their thing.
To make it easy to program those things, we have BlockingQueues in Java. Any thread can put things in and other threads can wait for something to come out. For example Runnables that they execute.
final BlockingQueue<Runnable> codeQueue = new LinkedBlockingQueue<>();
Thread serverThread = new Thread(new Runnable() {
#Override
public void run() {
while (!Thread.interrupted()) {
try {
Runnable code = codeQueue.take();
// call code in my context.
code.run();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
});
Thread clientThread = new Thread(new Runnable() {
#Override
public void run() {
codeQueue.add(new Runnable() {
#Override
public void run() {
System.out.println("Hello from Server Thread.");
}
});
}
});
In this example, clientThread causes serverThread to print "Hello from Server Thread." What serverThread does is also called an event loop. Because it waits for events and reacts to them.
Games typically have threads that do a (game) loop already. It's faily easy to add a line of code that checks for events and if it finds some to make it react to them. Anything bigger will already have a way to invoke code in different threads.
would calling a method on the main server thread from one of the client threads run that method on the client thread, or the server thread?
In the client thread.

Restarting a thread after it has been left

I have thread which contains a loop
while(isRunning){
}
isRunning is a Boolean variable with the value true, when some clicks on a button it gets false and so it leaves the loop and the run() function of the thread.
I want to create another button that on click it will reenter the run() function.
I am not sure if when I leave the run() function the thread dies or just stops.
I have tried using thread.run() but it didnt work.
Also I have looked for an answer in other's people questins about this matter but nothing seemed to help me. Thanks for the help
When a thread is finish processing it's code, There's no way of restarting it. You can either:
Create a new thread and pass the Runnable to that thread.
If you need to use that run() method often, use an Executor. You can use Executors.newSingleThreadExecutor(), which will supply you with a worker thread. (Reusable thread).
class Example {
static ExecutorService executor = Executors.newSingleThreadExecutor();
static Runnable run = new Runnable() {
public void run() {
}
};
public static void main(String[] args) {
//anytime you wanna run that code..
executor.execute(run);
}
}
If your thread runs to its end, it stops.
It will remain there for you to collect its return status until the thread is cleaned up.
To restart within the same thread, you need an extra control flow.
For instance:
while (restarted) {
while (isRunning) {
}
// Wait for a restart or end click
}
That is what so called worker threads in a thread pool do, which are intended for maximum performance.
But logically, you will probably simply want to create a new thread object and start that one.
new Thread(p).start();
Please read through java concurrency tutorial.
http://docs.oracle.com/javase/tutorial/essential/concurrency/
Just Maybe, guarded blocks might be useful for your case but your case is a little vague to recommend anything specific.
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

End execution of Thread without using its stop() method

I have a Swing form with a button, which is when clicked starts SocketServer for listening to incoming requests in a separate thread. Following is structure of classes I have.
MainForm : This is my main class which launches Swing Form. It has two buttons, "start server" and "stop buttons".
MySocketServer : This class is where SocketServer object exists, it has methods startServer() and stopServer().
Following is Start button's Click Event Body.
t = new Thread(new Runnable() //Object t is created globally in this main class.
{
public void run()
{
myss = new MySocketServer(); //Object myss has similar accessibility as t.
myss.startServer();
}
});
t.start();
And Following is Stop Button's Click Event Body
myss.stopServer();
if(t.isAlive());
System.out.println("Thread is still alive!!");
Though I can toggle SockeServer "start" and "stop" as my times I want, but I realize that everytime I start the server, new thread gets created and it remains active even though server is stopped using MySocketServer's method.
I can use stop() of Thread and stop the thread execution but since it is depreciated and I have studied that threads get ended once their run() method has executed completely, but I have startServer() method separated so that it can handle connected clients separately.
Please note that startServer() has While-Listen loop, so essentially run() method of thread is in infinite state of execution, until I explicitly call stopServer() and halt the loop.
what can be done here?
Firstly, you are right to not try to use Thread.stop(). It is potentially dangerous.
So what should you do?
One possibility might to be to write your server thread like this:
....
ServerSocket ss = new ServerSocket(...);
try {
while (keepGoing) {
Socket s = ss.accept(...);
try {
// do stuff
} finally {
// close socket
}
}
} finally {
// close the server socket
}
and have stopServer clear the keepGoing flag. But the problem is that the stop typically will come while the thread is blocked in the accept call, and there's nothing to unblock it.
Another possibility might be to call Thread.interrupt() on the thread. That causes some things to unblock, and throw an exception, but I don't think it will unblock the accept() call though. (However, this is still better than setting a flag if the "do stuff" part needs interrupting.)
The real solution (I think) is to close the ServerSocket. This will cause the ss.accept() call to unblock and throw an exception, which you need to handle in the server thread.
In your MySocketServer class in the while loop you need a flag which will test if it should keep running or not.
In your newly added shutdown method set the flag which the loop in the thread will test. Once the loop breaks and run() returns the thread will end.
You shouldn't use stop(). Take a look at this http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
The solution with infinite loop and start/stop flags is straightforward but leads to ineffective using of CPU time. The better way is to use wait/notify approach. The way you operate with MySocketServer gives me feeling that you have other infinite loop inside the startServer(). That's why you have to stop it. It would be better to wrap this loop into it's own thread internally and make start/stop methods operate with this thread state in wait/notify manner.
Forgot to mention, as your GUI runs in its own thread you can't escape start/stop flag inside the MySocketServer because using wait() in GUI thread will make it hanged.

How does one stop a thread without a stop() method?

I have question about the Java threads. Here is my scenario:
I have a thread calling a method that could take while. The thread keeps itself on that method until I get the result. If I send another request to that method in the same way, now there are two threads running (provided the first did not return the result yet). But I want to give the priority to the last thread and don't want to get the results from the previously started threads. So how could I get rid of earlier threads when I do not have a stop method?
The standard design pattern is to use a local variable in the thread that can be set to stop it:
public class MyThread extends Thread {
private volatile boolean running = true;
public void stop() {
running = false;
}
public void run() {
while (running) {
// do your things
}
}
}
This way you can greacefully terminate the thread, i.e. without throwing an InterruptedException.
The best way really depends on what that method does. If it waits on something, chances are an interrupt will result in an InterruptedException which you handle and cleanly exit. If it's doing something busy, it won't:
class Scratchpad {
public static void main(String[] a) {
Thread t = new Thread(new Runnable() {
public void run() {doWork();}
});
t.start();
try {
Thread.sleep(50);
} catch (InterruptedException ie) {}
t.interrupt();
}
private static void doWork() {
for ( long i = 1; i != 0; i *=5 );
}
}
In the case above, the only viable solution really is a flag variable to break out of the loop early on a cancel, ala #inflagranti.
Another option for event-driven architectures is the poison-pill: if your method is waiting on a blocking queue for a new item, then you can have a global constant item called the "poison-pill" that when consumed (dequeued) you kill the thread:
try {
while(true) {
SomeType next = queue.take();
if ( next == POISON_PILL ) {
return;
}
consume(next);
}
} catch //...
EDIT:
It looks like what you really want is an executor service. When you submit a job to an executor service, you get back a Future which you can use to track results and cancel the job.
You can interrupt a Thread, its execution chain will throw an InterruptedException most of the time (see special cases in the documentation).
If you just want to slow down the other thread and not have it exit, you can take some other approach...
For one thing, just like exiting you can have a de-prioritize variable that, when set, puts your thread to sleep for 100ms on each iteration. This would effectively stop it while your other thread searched, then when you re-prioritize it it would go back to full speed.
However, this is a little sloppy. Since you only ever want one thing running but you want to have it remember to process others when the priority one is done, you may want to place your processing into a class with a .process() method that is called repeatedly. When you wish to suspend processing of that request you simply stop calling .process on that object for a while.
In this way you can implement a stack of such objects and your thread would just execute stack.peek().process(); every iteration, so pushing a new, more important task onto the stack would automatically stop any previous task from operating.
This leads to much more flexible scheduling--for instance you could have process() return false if there is nothing for it to do at which point your scheduler might go to the next item on the stack and try its' process() method, giving you some serious multi-tasking ability in a single thread without overtaxing your resources (network, I'm guessing)
There is a setPriority(int) method for Thread. You can set the first thread its priority like this:
Thread t = new Thread(yourRunnable);
t.start();
t.setPriority(Thread.MIN_PRIORITY); // The range goes from 1 to 10, I think
But this won't kill your thread. If you have only two threads using your runnable, then this is a good solution. But if you create threads in a loop and you always sets the priority of the last thread to minimum, you will get a lot of threads.
If this is what is application is going to do, take a look at a ThreadPool. This isn't an existing class in the Java API. You will have create one by yourself.
A ThreadPool is another Thread that manages all your other Threads the way you want. You can set a maximum number of running Threads. And in that ThreadPool, you can implement a system that manages the Thread priority automatically. Eg: You can make that older threads gain more priority, so you can properly end them.
So, if you know how to work with a ThreadPool, it can be very interesting.
According to java.lang.Thread API, you should use interrupt() method and check for isInterrupted() flag while you're doing some time-consuming cancelable operation. This approach allows to deal with different kind of "waiting situations":
1. wait(), join() and sleep() methods will throw InterruptedExcetion after you invoke interrupt() method
2. If thread blocked by java.nio.channels.Selector it will finish selector operation
3. If you're waiting for I/O thread will receive ClosedByInterruptException, but in this case your I/O facility must implement InterruptibleChannel interface.
If it's not possible to interrupt this action in a generic way, you could simply abandon previous thread and get results from a new one. You could do it by means of java.util.concurrent.Future and java.util.concurrent.ExecutorService.
Cosider following code snippet:
public class RequestService<Result> {
private ExecutorService executor = Executors.newFixedThreadPool(3);
private Future<Result> result;
public Future<Result> doRequest(){
if(result !=null){
result.cancel(true);
}
result = executor.submit(new Callable<Result>() {
public Result call() throws Exception {
// do your long-running service call here
}
});
return result;
}
}
Future object here represents a results of service call. If you invoke doRequest method one more time, it attempts to cancel previous task and then try to submit new request. As far as thread pool contain more than one thread, you won't have to wait until previous request is cancelled. New request is submitted immediately and method returns you a new result of request.

Categories