Solved Killing a thread ?

Discussion in 'Plugin Development' started by Betagear, Jun 4, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    Betagear

    In a thread, I have a while loop that runs until the thread is interrupted, with a delay between all iterations.
    But, when I try to interrupt it inside the class, the server stops (Using Thread.currentThread().interrupt();).
    Here's the error :
    Code:
    [10:52:20] [Server thread/ERROR]: Encountered an unexpected exception
    java.lang.InterruptedException: sleep interrupted
        at java.lang.Thread.sleep(Native Method) ~[?:1.8.0_91]
        at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:540) [spigot-1.8.8.jar:git-Spigot-e4d4710-e1ebe52]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_91]
    [10:52:20] [Server thread/ERROR]: This crash report has been saved to: C:\Users\Moddingear\Desktop\Dev\BungeeCord\Serveur 1\.\crash-reports\crash-2016-06-04_10.52.20-server.txt
    [10:52:20] [Server thread/INFO]: Stopping server
    Yet the interrupted thread is running in another thread...

    Why ?

    So how should I interrupt/stop a thread ?


    SOLUTION :

    Use break; in the catch of Thread.currentThread.sleep();

    Use a boolean in your class to be accessible from another class that can clean up all of it's references.
     
    Last edited: Jun 4, 2016
  2. Offline

    I Al Istannen

    @Betagear
    How do you start the new thread? And why do you want to interrupt the thread you are currently in?
     
  3. Offline

    Betagear

    @I Al Istannen Using this :
    Code:
                        Thread t = new Thread(zv);
                        t.start();
     
  4. Offline

    I Al Istannen

    @Betagear
    From which thread do you call "Thread.currentThread().interrupt()"? Try printing "Bukkit.isPrimaryThread()" and "Thread.currentThread().getName()" before this instruction.
     
  5. Offline

    Betagear

    @I Al Istannen I call it from the zv class instanced in the created thread. I added a quick test as you said to see if it is running on the bukkit thread, and it's always false.

    I'm using this code when I try to destroy it, from inside the class :
    Code:
        public void cancel(){
            System.out.println("Destroyed");
            Thread.currentThread().interrupt();
            try {
                this.finalize();
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    and when I reload, I call cancel on all these instances of classes I have in an ArrayList.
     
  6. Offline

    I Al Istannen

    @Betagear
    Hmm I made a short test with this:
    Code:
          Thread t = new Thread(() -> {
             Runnable runner = () -> {
               Thread.currentThread().interrupt();
             };
             int counter = 0;
             while(true) {
               System.out.println("i am alive");
               try {
                 Thread.sleep(2000);
               } catch (InterruptedException e) {
                 System.out.println("Gone");
                 break;
               }
               if(counter == 3) {
                 runner.run();
               }
               counter++;
             }
           }, "Lol");
           t.start();
    
    And it ran as expected:
    i am alive
    i am alive
    i am alive
    i am alive
    i am alive
    Gone


    Seems like you interrupt the main thread too, somehow. Could you show a bit more of your code?

    EDIT: Changed the code, didn't realize what you meant.
     
  7. Offline

    Betagear

    When I initialize it :
    Code:
                        ZoneViewer zv = new ZoneViewer(l, player, zone, l.zc.getColor(player.getUniqueId(), zone.getOwnerGroup()).getColor());
                        ZonesViewed.add(zv);
                        Thread t = new Thread(zv);
                        t.start();
                        ViewerThreads.add(t);
    where ZonesViewed is an ArrayList of ZoneViewer, and ViewerThread an arraylist of Thread

    then, when I want to kill a ZoneViewer, I just call cancel() , but as I do it for all ZoneViewer in my ArrayList when I reload my server, it stops.

    and actually ViewerThreads is unused, it was used when I interrupted the threads externally.
     
  8. Offline

    I Al Istannen

    @Betagear
    And ZoneViewer is a runnable? (And I would follow naming conventions and start variables with a lowerCase letter and the camelCase ;))
    I haven't seen much of your code, but I think I did the exact same with my updated last post and it worked fine. Did you do something different?

    Could you print out the thread name, just before the interrupt? And then intialise all your threads with a special name (just a counter or a random integer to hex or I don't know what)? Bukkit.isPrimaryThread() isn't totally reliable, as stated in the Javadoc.
     
  9. Offline

    Betagear

    @I Al Istannen Yep, ZoneViewer is a runnable, and has the while(!Thread.currentThread().isInterrupted()) loop.
    I did the same as you, but somehow it doesn't stops the code.

    EDIT : I'm not using while(true). Will try that.

    EDIT 2 : Wasn't using break;
     
    Last edited: Jun 4, 2016
  10. Offline

    I Al Istannen

    @Betagear
    Final question: Does it work?
    If not, I think I'll need to ask you for a SSCCE (short, self contained, compilable example), as errors you can't reproduce are hard to come by.


    Dumb me didn't see the title. Sorry ;)
     
Thread Status:
Not open for further replies.

Share This Page