I\'m trying to stop a thread but I can\'t do that :
public class Middleware {
public void read() {
try {
socket = new Socket(\"192.168.1.8\", 20
"Many uses of stop()
should be replaced by code that simply modifies some variable to indicate that the target thread should stop running."—java.lang.Thread
Simply return;
from your while and the thread will die, no need to call stop() or interrupt(). If you want to do it externally then use this pattern and call requestStop()
.
class Scan extends Thread {
private volatile stop = false;
public void run() {
while (!stop) {
try {
// my code goes here
} catch (IOException ex) {
stop = true;
}
}
}
public void requestStop() {
stop = true;
}
}
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
//do something here
if(condition)
{
Thread.currentThread().interrupt();
}
}
The usual way to stop a thread is to have a volatile flag and then check that in the run method. i.e.
class Scan extends Thread {
volatile stop = false;
public void run() {
while (!stop) {
try {
// my code goes here
} catch (IOException ex) {
thread.currentThread().interrupt();
}
}
}
public void stop(){
stop = true;
}
}
You can then call scan.stop()
.
Rather than using Thread.stop() or Thread.interrupt() you can go for the external locks. Basically, when you try to utilize an intrinsic lock most of the time any interrupt you perform on the thread is uncontrollable.
A re-entrant lock provides you the methods as mentioned below
lock()
unlock()
tryLock()
lockInterruptibly()
isHeldByCurrentThread()
getHoldCount()
Check the below example
final ReentrantLock reentrantLock = new ReentrantLock();
@Override
public void performTask() {
reentrantLock.lock();
try {
System.out.println(Thread.currentThread().getName() + ": Lock acquired.");
System.out.println("Processing...");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + ": Lock released.");
reentrantLock.unlock();
}
}
This makes your code elegant and handle the interrupt in a better way.
There's really no reason you need to use a volatile
flag. Instead, just query the thread for its state with isInterrupted(). Also, why are you wrapping your Scan
thread object in another thread object? That seems completely unnecessary to me.
Here' what you should be doing
public class Middleware {
private Scan scan;
public void read() {
try {
// do stuff
scan = new Scan();
scan.start();
} catch (UnknownHostException ex) {
// handle exception
} catch (IOException ex) {
// handle exception
}
}
private class Scan extends Thread {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
// my code goes here
} catch (IOException ex) {
Thread.currentThread().interrupt();
}
}
}
}
public void stop() {
if(scan != null){
scan.interrupt();
}
}
}
Here's an example. Also, I wouldn't recommend extending Thread
.