Program not stopping thread - java

So I have a thread, which I previously could not get running but that's now been solved thanks to a member on this site, that question can be found here.
To stop my thread I created a boolean in the thread class and set it to false, if it is set to true then the thread should stop. I even check when I am stopping the thread by printing the thread but it prints true (which it should) but the thread keeps on running.
My thread (CheckFiles.java) class looks like this.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class CheckFiles extends Thread {
static boolean stop = false;
public void run() {
while (!stop) {
System.out.println("Thread " + stop);
try {
String line;
BufferedReader b = new BufferedReader(new FileReader(UserInterface.location));
while((line = b.readLine()) != null) {
Ststem.out.println(line);
}
} catch (IOException e) { System.out.println(e); }
}
}
}
To stop the thread I have a button and the code of it looks like this.
stopChecking.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
CheckFiles.stop = true;
System.out.println(CheckFiles.stop); //Prints true when pressed
}
});
Why is my thread not stopping, or is there a better way to do it?
EDIT: When I try interrupting the thread I get the syntax error
Cannot make a static reference to the non-static method interrupt() from the type Thread
Also when I make the boolean stop volatile the thread is still running.

The thread is blocking on b.readLine() as that line of code causes thread execution to halt until there is some input available.
To "force" stop, use Thread.interrupt()
E.g:
stopChecking.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
//To clarify the following uses a INSTANCE of CheckFiles, called CheckFiles.
//In other words, somewhere there was a declaration with the format:
// CheckFiles CheckFiles = ...
CheckFiles.stop = true;
CheckFiles.interrupt(); //Or whatever the name of your thread instance is
System.out.println(CheckFiles.stop); //Prints true when pressed
}
});
The internal reading loop should also be modified as such:
while(!stop && (line = b.readLine()) != null){
Ststem.out.println(line);
}
As the interrupt merely unblocks the I/O, we need to check if stop is still false before we proceed to do another blocking read.
As others have suggested, an alternative way is to directly invoke b.close() after setting stop = true;.
Edit:
Like Vakh has said, you should also make your boolean volatile so that updates to the stop variable are immediately visible to all threads.

You must declare stop as volatile:
static volatile boolean stop = false;
Basically, volatile implies that every thread accessing a volatile field will read its current value before continuing, instead of (potentially) using a cached value, which seems to occur in your case where the compiler assumes that the stop value is always false in your thread since it never writes an other value for it.

When you stop the bufferedreader with b.close(), wouldn't that stop the thread?

Use the threads interruption flag for termination:
public class FileChecker implements Callable<Void> {
private final File location;
public FileChecker(File location) {
this.location = location;
}
#Override
public Void call() throws Exception {
try {
while (!Thread.currentThread().isInterrupted()) {
try (BufferedReader b = new BufferedReader(new FileReader(location))) {
String line;
while ((line = b.readLine()) != null) {
if (Thread.interrupted()) {
throw new InterruptedException();
}
System.out.println(line);
}
}
}
} catch (InterruptedException ex) {
// restore interruption flag
Thread.currentThread().interrupt();
}
return null;
}
}
You can now schedule your file checker using an ExecutorService:
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> future = executor.submit(new FileChecker(...));
Stop the file checker by either cancelling the Future or shutting down the executor:
future.cancel(true);
executor.shutdownNow();

Related

Synchronized block still locked after thread restart

I try to restart thread but synchronized block in thread keep locked after restarted. I shouldn't change socket properties because some processes take too long but when network connection lost it hangs forever. I try to use InterruptedException but it doesn't work. Is there any way to release this lock?
public static void main(String[] args) {
try {
synchronizedBlock t1 = new synchronizedBlock();
t1.start();
Thread.sleep(500);
t1.cancel();
t1 = new synchronizedBlock();
t1.start();
} catch (Exception e) {
e.printStackTrace();
}
while (true) {
}
}
public class synchronizedBlock extends Thread {
boolean isRunning = true;
boolean isRunning2 = true;
public static Object[] locks = new Object[5];
public synchronizedBlock() {
for (Integer i = 0; i < 5; i++) {
synchronizedBlock.locks[i] = i;
}
}
public void cancel() {
isRunning = false;
interrupt();
}
public void socketProces() {
while (isRunning2) {
}
}
public void proces(int index) {
try {
synchronized (locks[index]) {
System.out.println("Synchronized Block Begin");
socketProces();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run() {
try {
System.out.println("Run begin");
while (isRunning) {
proces(1);
}
Thread.sleep(1);
} catch (InterruptedException e) {
//Do Something
} catch (Exception e) {
e.printStackTrace();
}
}
}
Result:
Run begin
Synchronized Block Begin
Run begin
When you start the synchronizedBlock thread you'll get a stack trace like this I think:
run -> proces -> socketProcess.
Then because isRunning2 = true, the thread will enter an infinite loop in socketProcess and never terminate.
Keep in mind that in Java there is no such thing as 'restarting' a thread. Once started, a thread can never be restarted. Indeed, you are creating two sycnchronizedBlock objects, not restarting a single object.
As a side note, it is generally problematic to overwrite static state in a class constructor, as you're doing with the locks variable, without synchronization.
The issue here is the Integer cache which is used in the for loop to initialize the synchronizedBlock.locks array:
for (Integer i = 0; i < 5; i++) {
synchronizedBlock.locks[i] = i;
}
When this code is run again, due to the constructor of the second synchronizedBlock, the synchronizedBlock.locks array contains the same Integer instances which where created when this for loop was executed for the first time. This means that the synchronized (locks[index]) lock will be on the same Integer object. As you have already one thread holding the lock for the Integer(1) object, the second thread waits outside the lock waiting for it to be released.
This is also problematic in combination with the fact that the first thread is not terminating. Your method
public void socketProces() {
while (isRunning2) {
}
}
is an endless loop as you don't change the value of isRunning2, ever. Also, the interrupt() method itself does not stop any thread. Instead, it sets just an internal flag in the Thread class, which can be checked with isInterrupted() and interrupted(). You have to check this flag and react on it like "Oh, someone wants me to stop, so I stop now".
To solve your problem you should at least quit your thread when the "isInterrupted" flag of the Thread instance is set. You can do it like this:
public void socketProces() {
while (isRunning2) {
if (Thread.interrupted()) {
return;
}
}
}
Instead of returning from socketProces() normally you could throw an InterruptedException like other methods do.
Also, depending on how you want to initialize/use the instances you want to lock on with synchronized(...), you might want to consider on how you create/fill the synchronizedBlock.locks array and which objects you want to use (the Integer cache might be problematic here). It depends on you if the creation of a new synchronizedBlock instance will/should/shouldn't create new objects to lock on in the synchronizedBlock.locks array.

Java - Allow one thread in a method without waiting

I've a situation where I need to implement a thread safe method, The method must be executed by only one thread at a time, And while the method is being executed by a thread, all other threads trying to execute the same method shouldn't wait and must exit the method.
Synchronization won't help here since threads will be waiting to execute the method sequentially.
I thought I would achieve this by making use of ConcurrentHashMap using below code, but not sure if this is the perfect way to implement it.
Class Test {
private ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<>();
public void execute() {
if (map.putIfApsent("key", new Object()) != null) { // map has value for key which means a thread has already entered.
return; // early exit
}
threadSafeMethod();
map.remove("key");
}
private void threadSafeMethod() {
// my code
}
}
You can do this without synchronization, with compare-and-swap using a boolean:
private AtomicBoolean entered = new AtomicBoolean(false);
public void execute() {
if(entered.compareAndSet(false,true) {
try {
method()
} finally {
entered.set(false)
}
}
}
You could use a ReentrantLock and specify a negative value for waiting time. In that case the scheduler will not try to wait if there is a thread already executing the code.
// define the lock somewhere as an instance variable
Lock lock = new ReentrantLock();
try {
var isAvailable = lock.tryLock(-1, TimeUnit.NANOSECONDS);
if(isAvailable) {
System.out.println("do work");
lock.unlock();
}
} catch (InterruptedException e) {
e.printStackTrace();
}

Stopping a thread in a Tomcat Application - which method?

I'm using the below implementation to stop a thread in Tomcat. The code works, but I'm wondering two things:
Is it necessary to have Thread.sleep() in the try statement of MyConsumer.java?
Instead of checking for my boolean flag, running, should I remove the concept of a flag and just check for while(!Thread.currentThread().isInterrupted)?
ServletContextListener:
public final class ApplicationListener implements ServletContextListener {
private Thread thread = null;
private MyConsumer k = null;
public ApplicationListener() {
}
#Override
public void contextInitialized(ServletContextEvent event) {
k = new MyConsumer();
thread = new Thread(k);
thread.start();
}
#Override
public void contextDestroyed(ServletContextEvent event) {
if (thread != null) {
k.terminate();
try {
thread.join();
} catch (InterruptedException ex) {
Logger.getLogger(ApplicationListener.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
MyConsumer.java:
public class MyConsumer implements Runnable {
private volatile boolean running = true;
public MyConsumer() {
}
public void terminate() {
running = false;
}
#Override
public void run() {
while (running) {
try {
doStuff();
Thread.sleep((long) 1000);
} catch (InterruptedException ex) {
Logger.getLogger(MyConsumer.class.getName()).log(Level.SEVERE, null, ex);
running = false;
}
}
}
Is it necessary to have Thread.sleep() in the try statement of MyConsumer.java
No. The sleep call, I presume, is there to make sure that doStuff() is executed with an interval of 1 second between every invocation, rather than executed continuously. If you want this 1 second interval, you need to leave the sleep call there. If you want doStuff() to be executed continuously, then you need to remove the sleep.
Instead of checking for my boolean flag, running, should I remove the concept of a flag and just check for while(!Thread.currentThread().isInterrupted)?
Yes, that's what I would indeed do. It would remove the need for the flag, and would allow stopping the thread as soon as possible, rather than having to wait for the sleep call to return, after 1 second. The other advantage is that you can check if the thread is interrupted inside the doStuff() method, in case it's a long-running method that you want to stop ASAP.
There's no reason for your thread to sleep just to check for interruptions. You can call Thread.interupted() there instead.
Regarding the boolean running flag, it provides similar functionality of interrupted, except that it's not triggered by methods that throw InterruptedException. Depending on whether it makes sense to stop normal flow of operation in those methods, you should use one or the other mechanism, but not both.
See http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html for a good overview of how interrupts are used.

Returning/Stopping the execution of a function on a keypress in Java

I have a certain function in my program that I want to stop on the press of a key. I have a native keyboard hook set up for that purpose. Right now, I call System.exit(0) when that key is detected. However, I don't want to exit the program, just stop that operation and return to where it was called. An example is given below.
public class Main {
public static void main(String[] args) {
System.out.println("Calling function that can be stopped with CTRL+C");
foo(); // Should return when CTRL+C is pressed
System.out.println("Function has returned");
}
}
I've tried putting the call to foo() in a thread so I could call Thread.interrupt() but I want the function call to be blocking, not non-blocking. Also there are blocking IO calls in foo() so I'd rather not deal with interrupts unless it's necessary, because I'd have to deal with ClosedByInterruptException exceptions and that has caused problems before.
Also the body of foo() is very long and has many function calls inside it, so writing if (stop == true) return; in the function is not an option.
Is there a better way to do this than making a blocking thread? If so, how? If not, how would I make a blocking thread?
How about this?
// Create and start the thread
MyThread thread = new MyThread();
thread.start();
while (true) {
// Do work
// Pause the thread
synchronized (thread) {
thread.pleaseWait = true;
}
// Do work
// Resume the thread
synchronized (thread) {
thread.pleaseWait = false;
thread.notify();
}
// Do work
}
class MyThread extends Thread {
boolean pleaseWait = false;
// This method is called when the thread runs
public void run() {
while (true) {
// Do work
// Check if should wait
synchronized (this) {
while (pleaseWait) {
try {
wait();
} catch (Exception e) {
}
}
}
// Do work
}
}
}
(taken from http://www.exampledepot.com/egs/java.lang/PauseThread.html not my own work)

Stopping looping thread in Java

I'm using a thread that is continuously reading from a queue.
Something like:
public void run() {
Object obj;
while(true) {
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
obj = objectesQueue.poll();
}
}
// Do something with the Object obj
}
}
What is the best way to stop this thread?
I see two options:
1 - Since Thread.stop() is deprecated, I can implement a stopThisThread() method that uses a n atomic check-condition variable.
2 - Send a Death Event object or something like that to the queue. When the thread fetches a death event, it exits.
I prefer the 1st way, however, I don't know when to call the stopThisThread() method, as something might be on it's way to the queue and the stop signal can arrive first (not desirable).
Any suggestions?
The DeathEvent (or as it is often call, "poison pill") approach works well if you need to complete all of the work on the queue before shutting down. The problem is that this could take a long time.
If you want to stop as soon as possible, I suggest you do this
BlockingQueue<O> queue = ...
...
public void run() {
try {
// The following test is necessary to get fast interrupts. If
// it is replaced with 'true', the queue will be drained before
// the interrupt is noticed. (Thanks Tim)
while (!Thread.interrupted()) {
O obj = queue.take();
doSomething(obj);
}
} catch (InterruptedException ex) {
// We are done.
}
}
To stop the thread t that instantiated with that run method, simply call t.interrupt();.
If you compare the code above with other answers, you will notice how using a BlockingQueue and Thread.interrupt() simplifies the solution.
I would also claim that an extra stop flag is unnecessary, and in the big picture, potentially harmful. A well-behaved worker thread should respect an interrupt. An unexpected interrupt simply means that the worker is being run in a context that the original programmer did not anticipate. The best thing is if the worker to does what it is told to do ... i.e. it should stop ... whether or not this fits with the original programmer's conception.
Why not use a scheduler which you simply can stop when required? The standard scheduler supports repeated scheduling which also waits for the worker thread to finish before rescheduling a new run.
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleWithFixedDelay(myThread, 1, 10, TimeUnit.SECONDS);
this sample would run your thread with a delay of 10 sec, that means when one run finishes, it restarts it 10 seconds later. And instead of having to reinvent the wheel you get
service.shutdown()
the while(true) is not necessary anymore.
ScheduledExecutorService Javadoc
In your reader thread have a boolean variable stop. When you wish for this thread to stop set thius to true and interrupt the thread. Within the reader thread when safe (when you don't have an unprocessed object) check the status of the stop variable and return out of the loop if set. as per below.
public class readerThread extends Thread{
private volitile boolean stop = false;
public void stopSoon(){
stop = true;
this.interrupt();
}
public void run() {
Object obj;
while(true) {
if(stop){
return;
}
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(stop){
return;
}
obj = objectesQueue.poll();
// Do something with the Object obj
}
}
}
}
public class OtherClass{
ThreadReader reader;
private void start(){
reader = ...;
reader.start();
}
private void stop(){
reader.stopSoon();
reader.join(); // Wait for thread to stop if nessasery.
}
}
Approach 1 is the preferred one.
Simply set a volatile stop field to true and call interrupt() on the running thread. This will force any I/O methods that wait to return with an InterruptedException (and if your library is written correctly this will be handled gracefully).
I think your two cases actually exhibit the same potential behavior. For the second case consider Thread A adds the DeathEvent after which Thread B adds a FooEvent. When your job Thread receives the DeathEvent there is still a FooEvent behind it, which is the same scenario you are describing in Option 1, unless you try to clear the queue before returning, but then you are essentially keeping the thread alive, when what you are trying to do is stop it.
I agree with you that the first option is more desirable. A potential solution would depend on how your queue is populated. If it is a part of your work thread class you could have your stopThisThread() method set a flag that would return an appropriate value (or throw Exception) from the enqueuing call i.e.:
MyThread extends Thread{
boolean running = true;
public void run(){
while(running){
try{
//process queue...
}catch(InterruptedExcpetion e){
...
}
}
}
public void stopThisThread(){
running = false;
interrupt();
}
public boolean enqueue(Object o){
if(!running){
return false;
OR
throw new ThreadNotRunningException();
}
queue.add(o);
return true;
}
}
It would then be the responsibility of the object attempting to enqueue the Event to deal with it appropriately, but at the least it will know that the event is not in the queue, and will not be processed.
I usually put a flag in the class that has the Thread in it and in my Thread code I would do. (NOTE: Instead of while(true) I do while(flag))
Then create a method in the class to set the flag to false;
private volatile bool flag = true;
public void stopThread()
{
flag = false;
}
public void run() {
Object obj;
while(flag) {
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
obj = objectesQueue.poll();
}
}
// Do something with the Object obj
}
}

Categories

Resources