0

I'm trying to stop a java thread from a different class, but unable to figure out. I have looked into the below links, googled a lot from past 2 days but unable to nail down. May be a simple thing which i need to change but i'm out of options and hence posting it here.

Referred Links

While typing the question, I referred the below links as well..
Stop a thread from outside

Below is my code sample. I'm able to start the WorkerThread from the MainThread and get into the loop. But unable to stop the thread started using the StopThread class.

I've also used the volatile option suggested in the below link.
http://tutorials.jenkov.com/java-concurrency/volatile.html

I feel I'm making a simple mistake, but not able to identify it.

//class WorkerThread
package main;
public class WorkerThread implements Runnable
{
    public WorkerThread() {
        isRunning = true;
    }
    public WorkerThread(boolean False) {
        isRunning = False;
    }
    private volatile boolean isRunning;
    public synchronized void stopThread() {
        isRunning = false;
    }
    public synchronized boolean IsThreadRunning() {
        return isRunning;
    }
    @Override
    public void run() 
    {
        int i = 1;
        while(isRunning)
        {
            System.out.println("Loop " + i);
            i++;
            try { Thread.sleep(2000); } 
            catch (InterruptedException e) { e.printStackTrace(); }
        }
    }
}

//class MainThread
package main;
public class MainThread 
{
    public static Thread t;

    public static void main(String[] args) 
    {
        t = new Thread(new WorkerThread());
        t.start();
    }
}

//class StopThread
package main;
public class StopThread 
{
    public static void main(String[] args) 
    {
        //What should i write here to stop the thread started by MainThread
        MainThread.t.interrupt();
    }
}
Community
  • 1
  • 1
  • Hmn, make `Thread t` public in MainThread; `public static Thread t;` above MainThread's `main()`, then call `t.stop()` in StopThread's `main()` – Charlie Dec 13 '14 at 16:02
  • 3
    Each time you run `main` method via `java ClassWithMainMethod` you are creating JVM process which can have its own threads, but runs code from `main` method. But if you run main from `MainThread` and from `StopThread` you will create two separate processes, not threads. You need to let these processes communicate. Maybe use sockets or RMI. – Pshemo Dec 13 '14 at 16:03
  • I'm also not clear on what the architecture of your program is. Do you have two processes that each call different main functions? If so, you are out of luck because that means two different JVMs that don't communicate with each other. If you want two separate threads then you need to rethink your code and give us an update. – Giovanni Botta Dec 13 '14 at 16:10
  • Application architecture is - when the main thread starts - it creates two worker threads - one for primary server and one for the DR. Each thread sends out a ArrayList packet over the network as object to a server socket running in a remote machine. When trying to stop these two threads created from the main thread outside the class - unable to figure out. – Vinay Sathyanarayana Dec 13 '14 at 16:20
  • You should use files to 'connect' different processes with each other. Let StopThread make a file '/tmp/StopThread' and MainThread check if that file exists; if it does, let MainThread stop the thread. This is difficult, but trust me, it's the easiest option. – Charlie Dec 13 '14 at 16:27
  • Ehm, the link you gave ([This one](http://stackoverflow.com/questions/8356303/stop-a-thread-from-outside)) is for Ruby, not Java – Charlie Dec 13 '14 at 16:30
  • @Charlie, oh sorry, I had copied many links in my notepad which i had referred to find a solution for this scenario. Hope i've pasted a different link.. – Vinay Sathyanarayana Dec 13 '14 at 16:35
  • @Charlie, thanks the the suggestion though. I thought of this initially, but creating a file seems to be the last option, as I thought if it is possible in threads. If no other option, I'll go that route. – Vinay Sathyanarayana Dec 13 '14 at 16:36
  • the example Runnable won't work with interruption because the Runnable has to be written to respond to the interruption. see http://stackoverflow.com/a/5915306/217324. however if IO is involved interruption won't work, you'll have to close the socket. (as written i think this question is a duplicate of the one I linked to, but from your comments I don't think that solves your actual problem.) – Nathan Hughes Dec 13 '14 at 17:16
  • I have a similar issue, and after much research (and head wall banging) I came to the conclusion that the main thread caller needs to have access to the run() function in order to interrupt it. Here is a good link: http://www.javatpoint.com/interrupting-a-thread If any one has over come the issue of having two classes interact on a thread level please say so! – Erik Ware Jan 02 '17 at 05:26

4 Answers4

1
public class MainThread 
{
    public static Thread t;

    public static void main(String[] args) 
    {
        t = new Thread(new WorkerThread());
        t.start();
    }
}


public class StopThread 
{
    public static void main(String[] args) 
    {
        MainThread.t.interrupt();
    }
}

It is not safe to call Thread.stop() it is listed as deprecated in JavaDocs

Also this may be just for the sake of this question, but why does your program have two main methods?

SemperAmbroscus
  • 1,308
  • 2
  • 12
  • 23
  • How different would this be from making isRunning a static variable and updating it from stopthread? – hemanth Dec 13 '14 at 16:07
  • @hemanth meh I am sure to some degree that that would work but this answer is easier to read and would be more useful to someone reffering to this question IMO – SemperAmbroscus Dec 13 '14 at 16:09
0

Make thread t a public member of class MainThread, and then just call MainThread.t.interrupt() from StopThread

0

You have an opportunity to make use of what you defined volatile variable and gracefully come out of thread like below:

public class MainThread 
{
    public static WorkerThread workerThread;

    public static void main(String[] args) 
    {
        workerThread = new WorkerThread();
        Thread t = new Thread(workerThread);
        t.start();
    }
}

public class StopThread 
{
    public static void main(String[] args) 
    {
        Main.workerThread.stopThread();
    }
}
SMA
  • 36,381
  • 8
  • 49
  • 73
  • I tried the above, but the worker thread still continues to run. I'm doing this in Eclipse, and when I run the 'StopThread' class, I still see the thread running in the output console, continuing with the number it printed earlier. Any thoughts? – Vinay Sathyanarayana Dec 13 '14 at 16:16
  • Running two seperated Java files don't have any connection. Trying to get MainThread's WorkerThread will give null, as it is not declined. You can interact between these seperate processes with files, but that's another point. – Charlie Dec 13 '14 at 16:25
  • @VinaySathyanarayana are you running two different jvm's? Then even interrupt wont work. You will need to issue kill command from unix or pkill from windows. – SMA Dec 13 '14 at 16:33
  • @Almas Shaikh, I've only one JVM and running all the above classes (MainThread and WorkerThread) in the same JVM. Not sure why interrupt and also the volatile public method to change the boolean value to false is also not stopping the thread. – Vinay Sathyanarayana Dec 13 '14 at 16:40
  • @Charlie please read what Vinay has to say. Vinay please update your original code and how are you running by updating the question. – SMA Dec 13 '14 at 16:45
  • @Almas Shaikh, I've updated the code I ran by updating my question. – Vinay Sathyanarayana Dec 13 '14 at 17:50
0

Note: This solution works but not a perfect solution.

You can write and read value of isRunning variable from a properties file. This way you can have interaction between two different java processes. ThreadWorker just creates file upon initiation & and just makes attempt to read the file after that. StopThread modifies the properties file when triggered which should be picked up by ThreadWorker.

Check below example:

public class ThreadWorker implements Runnable
{
    public volatile static boolean isRunning = false;

    public ThreadWorker() {
        Properties p = new Properties();
        p.setProperty("isRunning", "1");
        FileOutputStream out;
        try {
          //Writes all properties in appProperties file
            out = new FileOutputStream("appProperties");
            p.store(out, "---Thread Status----");
            out.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void run() 
    {
        int i = 1;
        String status = "1";
        while("1".equals(status))
        {
            status = getStatus();
            System.out.println("Loop " + i);
            i++;
            try { Thread.sleep(2000); } 
            catch (InterruptedException e) { e.printStackTrace(); }
        }
    }

    public String getStatus() {
        FileInputStream in;
        Properties p = new Properties();
        try {
            in = new FileInputStream("appProperties");
            p.load(in);
            return p.getProperty("isRunning");
            in.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

        } 

    }
}


//class StopThread
public class StopThread 
{
    public static void main(String[] args) 
    {
        Properties p = new Properties();
        p.setProperty("isRunning", "0");
        FileOutputStream out;
        try {
            out = new FileOutputStream("appProperties");
            p.store(out, "---Thread Status----");
            out.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

//class StopThread
public class StopThread 
{
    public static void main(String[] args) 
    {
        Properties p = new Properties();
        p.setProperty("isRunning", "0");
        FileOutputStream out;
        try {
            out = new FileOutputStream("appProperties");
            p.store(out, "---Thread Status----");
            out.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
hemanth
  • 1,033
  • 8
  • 12