-3

There are tons of questions asking basically the same, but using the solutions suggested there brings one problem for me.

Problem: If using a boolean to determine if my thread is allowed to keep running or not, the while loop checking if the stop() method has been called and thus, if the "interrupt"-variable has been set, holds the program flow right there in the while loop. So the actual purpose of my threads, which is running in the background, gets lost.

class MyThread implements Runnable
{
    private String name;
    private long seconds;
    private boolean exitThread = false;

    MyThread(String name, long seconds)
    {
        this.name = name;
        this.seconds = seconds;
    }
    public void run()
    {
        while (!exitThread) 
        {
            try 
            {
                Thread.sleep(seconds* 1000);
                System.out.println("Thread \"" + name+ "\" started...");
                return;
            } 
            catch (InterruptedException e) 
            {
                e.printStackTrace();
            }
        }
    }

    public void stop()
    {
        this.exitThread = true;
    }
}

The while-loop in method "run()" prevents the program from executing, til the thread has finished/been killed, instead of running in the background as my thread is supposed to be.

Follow-up question: Why would I use the keyword "volatile" on my boolean variable since I want my individual created threads to be able to stop as individual, not to stop all thread if the boolean variable is set "true" once on one running thread?

EDIT: Instantiating of threads:

    public void initThreads()
    {
        MyTimerThread newThread = new MyTimerThread("Thread1, 10);
        newThread.run();
        threadList.add(newThread);
        MyTimerThread newThread = new MyTimerThread("Thread2, 30);
        newThread.run();
        threadList.add(newThread);
    }
freeprogramer233
  • 193
  • 2
  • 11

3 Answers3

3

You have to replace the return with continue. Return ends the while loop and thus your own Thread implementation.

class MyThread implements Runnable
{
    private String name;
    private long seconds;
    private boolean exitThread = false;

    MyThread(String name, long seconds)
    {
        this.name = name;
        this.seconds = seconds;
    }
    public void run()
    {
        while (!exitThread) 
        {
            try 
            {
                Thread.sleep(seconds* 1000);
                System.out.println("Thread \"" + name+ "\" started...");
                continue;
            } 
            catch (InterruptedException e) 
            {
                e.printStackTrace();
            }
        }
    }

    public void stop()
    {
        this.exitThread = true;
    }
}

Because continue is the last statement in the method you can also remove it.

Follow Up question: The keyword volatile indicates that a variable is used on multiple threads and shouldn't be cached on one specific thread.

The voted answer on this question explains it in further detail: Do you ever use the volatile keyword in Java?

EDIT: Here is an example I made to answer the note you left on this answer:

class MyThread implements Runnable
{
    private String name;
    private long seconds;
    private volatile boolean exitThread = false;

    private int count;

    MyThread(String name, long seconds)
    {
        this.name = name;
        this.seconds = seconds;
    }

    public void run()
    {
        while (!this.exitThread)
        {
            try
            {
                if(!Thread.currentThread().isInterrupted())
                {
                    Thread.sleep(this.seconds * 1000);
                    System.out.println("Runnable '" + this.name + "' run() " + this.count);
                    this.count++;
                }
                continue;
            }
            catch (InterruptedException e)
            {
                System.out.println("Runnable '" + this.name + "' ended.");
            }
        }
    }

    public void stop()
    {
        this.exitThread = true;
    }
}

which you can use like:

MyThread runnable = new MyThread("Task 1", 1);
Thread threadA = new Thread(runnable);
threadA.start();

try 
{
    System.out.println("Sleeping Main Thread.");
    Thread.sleep(4 * 1000);
    System.out.println("Main Thread Continued.");
}
catch (Exception e)
{
    e.printStackTrace();
}

runnable.stop();

while(!threadA.isInterrupted())
{
    threadA.interrupt();
}

And outputs like:

Sleeping Main Thread.
Runnable 'Task 1' run()0
Runnable 'Task 1' run()1
Runnable 'Task 1' run()2
Runnable 'Task 1' run()3
Runnable 'Task 1' run()4
Runnable 'Task 1' run()5
Runnable 'Task 1' run()6
Runnable 'Task 1' run()7
Runnable 'Task 1' run()8
Main Thread Continued.
Runnable ended.

Note that you implemented the Runnable interface. This means that your class isn't an Thread. Therefor calling .run() on the runnable runs it in the current thread.

If you want to do more with multi-threading I suggest you to read about ThreadPooling.

Community
  • 1
  • 1
Wesley
  • 855
  • 1
  • 9
  • 23
  • Your code-example (using continue) sadly does not do what i expected. I want my instantiated threads to run in the background as long as "exitThread" is not set or the thread simply finished it's run()-method. But it seems that the while-loop stops the program flow because the program waits til the thread finished til further executing my java program, kind of like using "Thread.join()". – freeprogramer233 Aug 04 '15 at 11:03
  • @freeprogramer233 I've added an example. Note that runnables are not Threads. Please accept this answer if it answers your question. – Wesley Aug 05 '15 at 10:24
0

Replace newThread.run(); with newThread.start();

talex
  • 17,973
  • 3
  • 29
  • 66
0

Why would I use the keyword "volatile"...?

The Java Language Specification does not require thread B to ever see the change to exitThread if thread A updates exitThread without any form of synchronization.

In practice, thread B may see the update anyway, or thread B may see the update after some time has passed. What actually happens depends on what JVM you are running and what operating system you are running, and what hardware it all is running on. But, it is possible, in theory, that thread B will never see the update.

If you add volatile to the declaration of exitThread, then the JVM is required to immediately propagate the update from thread A to thread B.

The rules may seem strange, but they make more sense once you learn how the memory system works in a multi-CPU computer. On most architectures, accessing a variable (i.e., a memory location) that does not need to be shared between threads can be much more efficiently than accessing a shared variable. The volatile keyword is how you say, "this variable needs to be shared" in Java.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57