2

I am 100% sure that Thread.sleep(3000); should throw InterruptedException either if the thread's interrupted status was set to true before or during the sleep call. See Calling Thread.sleep() with interrupted status set?

But I never get an exception when I interrupted the thread beforehand, only during the 3 seconds of sleep. How can this be?

Here is the concept of my code:

public class MyView extends CustomComponent implements View {
    private Thread importThread;
    private Collection<File> allUploadFiles = new HashSet<>();

    public MyView(){
        allUploadFiles.add(new File("/foo/bar.xlsx"));
        allUploadFiles.add(new File("/foo/bar.xlsx"));
        allUploadFiles.add(new File("/foo/bar.xlsx"));
        allUploadFiles.add(new File("/foo/bar.xlsx"));

        createMainLayout();
    }

    private void createMainLayout(){
        // Builds the layout here, including the upload button:
        MultiFileUpload upload = new MultiFileUpload(uploadFinishedHandler, uploadStateWindow, true);
        upload.setAllUploadFinishedHandler(this::allUploadFinishedHandler);
    }

    private void allUploadFinishedHandler(){
        final UI ui = UI.getCurrent();
        final VaadinSession session = VaadinSession.getCurrent();

        importThread = new Thread(() -> {
            UI.setCurrent(ui);
            VaadinSession.setCurrent(session);

            for (File uploadFile : allUploadFiles){
                try {
                    // system output to see when the thread sleeps
                    System.out.print("start sleep");
                    Thread.sleep(3000);
                    System.out.print("end sleep");

                    MyImporter.import(uploadFile); // takes about a minute
                } catch (InterruptedException e){
                    Thread.currentThread.interrupt(); // keep the interrupted status
                    System.out.print("InterruptedException thrown!");
                    break;
                }
            }

            allUploadFiles.clear();
        });

        importThread.start();
    }

    /**
    * this is the clickListener of the interruptImport Btn which I left out in this codesample
    */
    public void interruptImport(){
        importThread.interrupt();
    }
}

Whenever I interrupt the importThread between the system-output of "start sleep" and "end sleep", an InterruptedException is thrown and everything works fine.

But when I interrupt it anytime else, nothing happens, the thread keeps importing file after file. The Thread.sleep(3000); lets it wait for 3 seconds but there is no exception being thrown.

I don't know what I'm doing wrong and could really need some help!


Edit: I replaced the import method with a keep-me-busy method as suggested by k5_, The problem remained.

I then added this codeblock just within the uploadFile-forloop and it worked (Edit 2: not consistently. I can't yet see why)

if(Thread.interrupted()){
    Thread.currentThread().interrupt();
    System.out.print("interrupted status detected manually");
    break;
}

but if I use Thread.currentThread().isInterrupted() in the if-condition it doesn't work.

Why does Thread.interrupted() work but not Thread.currentThread().isInterrupted() or even Thread.sleep(3000)

kscherrer
  • 5,486
  • 2
  • 19
  • 59
  • Most likely `MyImporter.import()` resets the `interrupt` flag from the Thread. Can you paste the `import` method? – k5_ Aug 24 '18 at 14:08
  • @k5_ no I can't share that. It reads values from the xlsx file, creates an object with them and saves that into the db. The import method does not use or modify Thread at all. – kscherrer Aug 24 '18 at 14:11
  • Can you replace the `import` method with a busy loop. (Something that counts a few times to a billion on a static variable). And see if the error persists. – k5_ Aug 24 '18 at 14:12
  • I would implement an if interrputed() after for loop to see if we need to stop/break the thread – Nghia Do Aug 24 '18 at 14:19
  • @Tinkeringbell no – kscherrer Aug 24 '18 at 14:53
  • Is `allUploadFinishedHandler()` invoked by the same thread that invokes `interruptImport()` (presumably the UI thread)? If not, you could have a visibility problem reading the value of `importThread`. Add logging to `interruptImport()` and `allUploadFinishedHandler()` that will enable you to determine if they are using the same thread, and that the `interrupt()` call actually succeeds (rather than throwing a null pointer or interrupting an old thread). – erickson Aug 24 '18 at 17:07
  • @erickson both of those methods are invoked by the request thread, but they are separate requests. I will add logging first thing on monday morning, thank you for your comment. – kscherrer Aug 24 '18 at 17:36
  • 1
    Okay, if this is driven by web requests, the methods are likely to be invoked by different threads from a pool. Any member variables accessed by different threads should be `final` or `volatile`. – erickson Aug 24 '18 at 17:50
  • @Cashbee i still think your import consumes the interrupt flag, can you provide your busy loop? – k5_ Aug 25 '18 at 09:21
  • Are you sure you are interrupting the right instance of 'importThread'? I mean you create a new instance every call to 'allUploadFinishedHandler'. – Boaz Aug 28 '18 at 11:37
  • @Boaz `allUploadFinishedHandler` is called only once (I upload only one batch of files). defining the `importThread` as volatile as erickson suggested helped a bit but there are still inconsistencies. I have put this project aside for now until I have more experience with Threads. I can't even formulate my question here precise enough. – kscherrer Aug 28 '18 at 11:42

0 Answers0