简体   繁体   中英

Thread Join + ScheduledExecutorService not working as expected

In the below code snippet, I notice the following sequence of execution. Why is the control going back to the flow outside the someMethod() before completing the activity in the someTask block? Shouldn't it complete everything inside thread2 before moving to the next line of code as thread2.join() has been invoked?

System.out.prinltn("inside someMethod...");
System.out.println("after thread2 .....");
System.out.prinltn("inside someTask......");
public static void main(String args[]) {
        Thread thread1 = new Thread(new someclassimplementingRunnable());
        thread1.start();
        try {
            thread1.join();
            Thread thread2 = new Thread(new Runnable() {
                public void run() {
                    someMethod();

                }
            });
            thread2.start();
            thread2.join();
            System.out.println("after thread2 .....");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("outside try-catch");
    }
public static synchronized void someMethod(){
System.out.prinltn("inside someMethod...");
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Runnable someTask = () -> {
System.out.prinltn("inside someTask......");
};
executor.scheduleAtFixedRate(someTask , 0, 2, TimeUnit.SECONDS);
}

it is working as expected. you're just expecting the wrong outcome;)

Thread2 finishes it's work once the executor starts working, and frankly, its a miracle you get to see "inside someTask" at all, as the executor and it tasks will be garbage collected once "someMethod" finishes working. (ie the Executor doesn't stay alive outside of someMethod, and there is no blocking operation at the end of someMethod that waits for the executor to finish).

i would even wager that if you run this code enough times, there will be instances when you won't see the line "inside someTask" because of random OS/process scheduling.

there is no line that makes "someMethod" wait, and so Thread2 finishes its work and it passes.join() and you see the print out "after thread2".

also, remember that the Console is not a synchronic output service. when multiple threads send output to the console, its not guaranteed to appear in the same order. so it is not a good indication of the order of events in a multithreaded environment.

I found the solution and actually its pretty simple, checking the condition while(.executor.isTerminated()) does the job. It ensures the next statements are executed only after the executor has done its job.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM