1

I tried to create a engine helpful for the Debugging of my code, but it seems it needs Debug on it's own... The mainfunction is a javax.swing-applikilation, from which I open other subclasses of the packages. I tried to put in a thread for the input in the Shell (I'm working with Eclipse), but the problem is that it doesn't work the second times it's opened. The first Time it does! I doesn't find any Ressource leaks or else. Somehow, it just outputs a empty line again and again. The break has to be with the opening and closing of the input-class, but the only thing I was able to find were tutorials how to use or to terminate threads (What I'm doing there, look at the end with the InterruptedException). Weird is, that it does break the second time opened to this semi-errored state. usually, it would output a Exception the second opened time, but I coded it to do nothing instread.

Code:

import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

public class Commander extends Thread {

/**
 * @Author Ninto
 */
static String Input = "";
private static Logger log=null;
boolean running = true;
boolean scanning = true;
Commander(){
    setDaemon(false);
}
public Commander(){}

@Override
public void run() {
    running = true;
    scanning = true;

    input in = new input(); //Opens the Thread of the Subclass input
    in.start();

    while(running) {
        TimeUnit.MILLISECONDS.sleep(25);
        if(!Input.equals("")) {
            switch(Input) {
                case "something_else": break; //Do the debug there, like controlling the variables used by other classes
                case "exit" : running = false; break; //Should close this Class & subclasses
                case "stop" : System.exit(0); break; //Ends the program. Not to use!
            }   
        }

        Input = "";
        scanning = true;
    }
    in.interrupt(); //Should break the Subclass - thread
    TimeUnit.MILLISECONDS.sleep(100);
    running = false;
}

class input extends Thread {
    input() {setDaemon(true);} //To close the Thread with the exit of the Programm if still existing
    private String Input = " ";

    @Override
    public void run() {
        Scanner sc = new Scanner(System.in);
        try {
            while(true) {
                if(isInterrupted()||!running) {
                    log.Log2("Spacecommander/Input","Stop Thread");
                    sc.close();
                    return;}
                while(!scanning) {TimeUnit.MILLISECONDS.sleep(125);}
                TimeUnit.MILLISECONDS.sleep(250);

                try{this.Input  = sc.nextLine();}
                catch(NoSuchElementException e) {scanning = false;}
/*There does it break the Second time the Thread is used.
Another start of the Thread does the Same, only the first Time does it work.*/
                Commander.Input = this.Input;
                log.Log2("INPUT",Input);
                this.Input = "";
                scanning=false;}
        }
        catch(InterruptedException e) { //if this is called, it closes the Scanner and should exit the Programm.
            sc.close();}
        sc.close();
    }
}

}
Ninto
  • 123
  • 5
  • 2
    Consider using Java naming conventions to make your code easier to read. Class names should start with uppercase so `class input` should be `class Input`. Anyway `sc.close();` closes not only Scanner, but also its resource, here `System.in` so you can't use it later. – Pshemo Jul 07 '18 at 11:59
  • 1
    Also avoid extending Threads (it can cause you a lot of unexpected problems, especially if you start to `notify()` things). You don't really want to create class different than thread, you want to *use* thread "worker" to execute *task* you describe in `run()` method of class which `implements Runnable`. More info: [“implements Runnable” vs. “extends Thread”](https://stackoverflow.com/q/541487) – Pshemo Jul 07 '18 at 12:02
  • Yeah, but first, I already tryed the different methodes to open and close the Threads and second - I do open the Ressource at the start of the run()-method. So it opens the Ressource, but the closing "locks" it for the later parts of code? – Ninto Jul 07 '18 at 13:12

1 Answers1

0

Think the problem is the various calls to sc.close() . Because the Scanner was created against System.in, this will be closed too.

Once the close() calls are removed, Eclipse will warn you about a resource leak - in your case it's right to ignore this, e.g. :

    @SuppressWarnings("resource")
    Scanner sc = new Scanner(System.in);

The other common technique in this situation is to keep the Scanner instance to be used by the next thread - e.g. in a shared static variable.

df778899
  • 10,703
  • 1
  • 24
  • 36