1

im kind of new to java threads and ive just ran into a problem with a group project:

//edit: the program is a JFrame which needs a kind of "relaunch" to load the propertie file changes.

We've got a program where you are able to change some properties. For the changes to take effect, the program needs a restart / new launch with new JVM (seems to me?)

The problem is following:

I've already made a Thread which actualy starts our program and later on, the change will trigger the program to create a new thread. This is working, but im unable to kill the old thread. And if i try to do it ("X" or programmatically) i kill both instances at the same time. So there're actualy no 2 threads? - otherwise they should be treated seperatly, shoudln't they?

On the other hand when using Thread.currentThread().interrupt() both instances will remain, but im unable to do literally anything.

Thread starter:

public static void createNewInstance() {
prog = new Runnable() {
        @Override
        public void run() {
            try {
                 //loading propertie data into String[] array..
                 Start.main(String[] array);
                 while (true)  {
                        if (!isRunning) {
                            currentThread().interrupt();
                            createNewInstance();
                            isRunning = !isRunning;
                        }
                 }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    };
    new Thread(prog).start();
}

and at the change event:

        MyThread.isRunning = false;
        Thread.currentThread().interrupt();

As this is new to me and i can't figure out how i should achieve this im thankful for any kind of advice and any kind of mistake i've made so far. (Sorry for any kind of mistakes - im not a native speaker)

Thanks in advance!

----Workaround solution:----

In my case the propertie change was related to a new language setting: DE ->EN
My Messages:
public class Messages { private static String bundle_name = "com.ttr.language.messages" + new PropertiesClass().getProperty("lang"); //$NON-NLS-1$ private static ResourceBundle resource_bundle = ResourceBundle.getBundle(bundle_name);

Then I added this method to Messages class:

public static void updateProperties(String language) { bundle_name = "com.ttr.language.messages" + language; resource_bundle = ResourceBundle.getBundle(bundle_name); }

And used it in my program:

props.setProperty("lang", "EN"); <- example Messages.updateProperties(props.getProperty("lang"));
//dispose window and start login

Slajoc
  • 59
  • 1
  • 8
  • You actually interrupting the current thread, not the one that might expect interruption. You need the instance of thread that created in `createNewInstance()` to interrupt properly. – M. Prokhorov Mar 03 '17 at 17:28
  • Also, I'm pretty sure you don't need the thread to interrupt itself. You can just allow it to leave the body of your Runnable, at which point it will stop normally. – M. Prokhorov Mar 03 '17 at 17:30
  • Hi, thanks for the fast reply! Do i have to pass it all along to the change event? We've got quiete a lot of classes... Or am i able to do something like `getInstanceOf(MyThread).currentThread()` ? – Slajoc Mar 03 '17 at 17:37
  • No, no. Interruption is intended to actually interrupt the thread that might be in some long-running task that you don't want to wait for finishing. For your simple case you can just make `isRunning` volatile and comment out all interruptions I'm pretty sure. After that, you'll want to look into different wait-notify patterns, etc, just to see what's there and how you can further improve you code. – M. Prokhorov Mar 03 '17 at 17:42
  • Okay, i've understood why i should use `volatile` but my problem is - sorry for not mentioning it - that the `Start.main(String[] array);` is a jframe/panel/jdialog at the current time of change event and will not just finish off. Im kind of helpless i guess... – Slajoc Mar 03 '17 at 17:56
  • You should take a look at `java.util.concurrent` and use some of the higher-level constructs from there. raw threads, 'interrupt', `volatile`, these are all ways to spectacularly shoot yourself in the foot while trying to get something straightforward done. – pvg Mar 03 '17 at 18:08
  • Are you running all GUI operations in the Event Dispatch Thread (EDT)? – Lew Bloch Mar 03 '17 at 19:14
  • Hi, i do think so. Btw I've just looked into ExecutorService but its the same problem i guess, or maybe i just think to complicated.. I want to open my app on a new thread so i can close the old one and leave the new one open.. – Slajoc Mar 03 '17 at 19:34
  • is it possible to do something like [this](http://stackoverflow.com/a/4194224/6278217) but actualy dont restart the app but open a new instance of it and then closing the old instance? – Slajoc Mar 04 '17 at 01:06
  • @Slajoc From what I understand you want to start a new instance of a thread and kill its previous instance... Right??? – Ayush Bansal Mar 04 '17 at 04:19
  • @Ayush Bansal that's correct but every time I do so, either both threads get killed or none of them and they just remain like 'interrupted'... – Slajoc Mar 04 '17 at 11:56

1 Answers1

1

Let's say XThread is the thread which implements your functionality.When a change is triggered you could call terminateThread() to stop the previous running thread and call getInstance() to run the new thread with new properties.

 class XThread implements Runnable{

        private static Thread rT = null;
        private XThread()
        {}
        public static void terminateThread()
        {
            rT = null;
        }

        public static Thread getInstance()
        {
            if(rT==null)
            {
                rT = new Thread(new XThread());
            }
            return rT;
        }

        public void run()
        {
         //whatever functionality you want to add
        }
    }

Hope this helps :)

Ayush Bansal
  • 702
  • 1
  • 7
  • 17
  • Hi, thanks for that. Maybe im doing sth wrong, but i cant get this to work. If im using sth like `public void run() { System.out.println("start"); Thread.sleep(5000); System.out.println("exit"); terminateThread();` it just works like a charm and terminates right after printing exit. However, if im trying to start my program instead of the first `System.out.println("start");` it runs the program, runs the `Thread.sleep()` but does not terminate my program afterwards..? – Slajoc Mar 04 '17 at 18:40
  • Try like this... https://jpst.it/UMR2 . Forgive me for improper indentation . Are you using ```SwingUtilites.invokeLater()``` to run your GUI code. – Ayush Bansal Mar 05 '17 at 05:39
  • A useful link http://stackoverflow.com/questions/3551542/swingutilities-invokelater-why-is-it-needed – Ayush Bansal Mar 05 '17 at 05:39
  • Hi im using `invokeLater()` and i used your pastebin code... When launching, the new frame is created and the old thread maybe stops, but the old frame still lasts there. How do i get rid of this old frame? `dispose()` does not work for me in this project and `System.exit(0)` kills the whole JVM... Sorry for that but i still dont get how i can get rid of this old frame but keeping the new one alive.. Thanks for your patience and help so far! – Slajoc Mar 05 '17 at 11:29
  • If I'd use `dispose ()` which works in a test case: does my new Thread / program overwrites the freed memory of the first one? I have to ensure that there is no chance of getting data from this old thread / frame. – Slajoc Mar 05 '17 at 12:17
  • i just found a workaround for my problem: instead of launching a new Thread with new propertie settings, i've managed to change the settings during the runtime by just logging off the main program and reloading the ResourceBundle / reinitialize it again. Anyways thank you and the rest of you guys up there ^ :D for helping me out. I will mark this answer as correct answer due to the fact that this would have been the answer when i'd have had used it. – Slajoc Mar 05 '17 at 17:08
  • Could you please share that over here ? – Ayush Bansal Mar 05 '17 at 17:34
  • Hi, added solution in my [question](http://stackoverflow.com/q/42584993/6278217). – Slajoc Mar 05 '17 at 19:12
  • ```If I'd use dispose () which works in a test case: does my new Thread / program overwrites the freed memory of the first one? I have to ensure that there is no chance of getting data from this old thread / frame.``` Since we are doing this ```rT=null``` , i suppose there's no way to access previous data thread and moreover we are reassigning the variable . I will look into it programmatically and let you know (if you are interested). – Ayush Bansal Mar 06 '17 at 11:45
  • I'd be quite interested in this as I have read about this. It was quoted that after the `dispose ()` or `null` the memory would be freed but there would be a chance of getting back this freed memory and stuff. As I'm new to this I might got it wrong. But if this actually kills all the traces this would be quite awesome in my opinion as I am serious about security. – Slajoc Mar 06 '17 at 12:45