5 implementation methods for Java multithreaded task timeout end __java

Source: Internet
Author: User
Tags static class

When writing concurrent programs in Java, it is often the case that a thread has been unresponsive for a large amount of computation or blocking, and we may be impatient (or not wanting to make it occupy too many resources) to terminate it in time, which requires the skill to end the task timeout. When I first approached multithreading, I thought the API would provide such a multithreaded class: thread (Runnable R, long timeout), and the second parameter was used to set the timeout time, but that's not the case. Because such classes are not universal, the goal of object-oriented design languages is to achieve higher levels of abstraction, so the system provides only a wider range of timing classes and other classes of methods. This requires us to use these tools to reach the end of the task timeout. Don't talk much, straight to the point. (PS: Because of the limited level of authors, these methods only give you a few ideas, may not be textbook-style standard case) method one: Using Thread.Join (long million)

(First of all, I understand the Join method, it is understandable that you can skip the method, and before you understand it, explain another common sense, that is, the current thread (called the target thread, because it is the target task that we want to end the timeout) and the start call, Must be done on another thread (at least the main thread, or other threads different from the main thread), where we assume the main thread and call it a dependent thread, because the target thread was created inside him. The introduction of these common sense can further explain that the literal meaning of join is to have the target thread join the dependency thread, or to wait for the target thread to execute until the end (if no time-out parameter is set) in the dependent thread. The timeout parameter (assumed to be 5 seconds) is set to do so. After invoking a join in the dependency thread, it is tantamount to telling the dependent thread that now I'm inserting into your thread, that two threads are combined, equivalent to a thread (if you do not insert, the target thread and the dependent thread are executing in parallel), and the target thread is inserted in front of the main path, so the target thread executes first, but your main thread only needs to wait for me for 5 seconds, 5 seconds, and it's important that, whether I finish it or not, we're both separated, and then it's going to be two parallel threads, not the target thread that ends up executing directly.

This method is actually a bit far-fetched, because its main function is to synchronize between multiple threads. But because it provides a method with parameters (so this also gives us a broader idea that we can all try to use it to implement the timeout task with a timeout parameter), so we can use it to implement it. Note that the unit of the parameter here is a fixed millisecond, unlike the following function with units. See examples for specific uses:

public class Jointest {public static void main (string[] args) {Task Task1 = new Task ("One", 4);
        Task Task2 = new Task ("Two", 2);
        thread T1 = new Thread (TASK1);
        Thread t2 = new Thread (TASK2);
        T1.start (); try {t1.join (2000);//Waiting for T1 in the main thread to execute 2 seconds} catch (Interruptedexception e) {System.out.printl
            N ("T1 interrupted when waiting join");
        E.printstacktrace (); } t1.interrupt ();
        It is important to interrupt T1 because it has been in execution for 2 seconds.
        T2.start ();
        try {t2.join (1000);
            catch (Interruptedexception e) {System.out.println ("T2 interrupted when waiting join");
        E.printstacktrace ();
    The class Task implements Runnable {public String name;

    private int time;
        The public Task (String s, int t) {name = S;
    Time = t; public void Run () {for (int i = 0; i < time; ++i) {System.out.println ("task "+ name +" "+ (i + 1) +" round ");
            try {thread.sleep (1000); The catch (Interruptedexception e) {System.out.println (name + "is interrupted when")
                Calculating, would stop ... "); Return Note that if this is not returned, the thread will continue to execute, so the task times out and then returns the}}}

Wait for the T1 execution in the main thread after 2 seconds, to interrupt (instead of calling the stop directly, this method has been discarded), and then in the T1 will produce an interrupt exception, in the exception to deal with the matter, must return, must return, If you do not return, T1 will continue to execute, except in parallel with the main thread. method Two: Future.get (long million, Timeunit unit) with Future.cancle (true)

The future series (its subclasses) can be implemented with the simplest future interface implementations.

public class Futuretest {static Class Task implements callable<boolean> {public String name;

        private int time;
            The public Task (String s, int t) {name = S;
        Time = t;
                @Override public Boolean Call () throws Exception {for (int i = 0; i < time; ++i) {
                SYSTEM.OUT.PRINTLN ("task" + name + "Round" + (i + 1));
                try {thread.sleep (1000); The catch (Interruptedexception e) {System.out.println (name + "is Interrup
                    Ted when calculating, would stop ... "); return false;
        Note that if this is not returned, the thread will continue to execute, so the task times out and then returns the result with} return true;
        } public static void Main (string[] args) {Executorservice executor = Executors.newcachedthreadpool ();
        Task Task1 = new Task ("One", 5); Future<boolean>F1 = Executor.submit (TASK1); try {if (F1.get (2, Timeunit.seconds)) {//future will take the result after 2 seconds System.out.println ("one complete s
            Uccessfully ");
            The catch (Interruptedexception e) {System.out.println ("future interrupted while Asleep");
        Executor.shutdownnow ();
            catch (Executionexception e) {System.out.println ("future error while attempting to get task results");
        Executor.shutdownnow ();
            catch (TimeoutException e) {System.out.println ("Future Time timed out");
            F1.cancel (TRUE);
            Executor.shutdownnow ();
        Executor.shutdown ();
        finally {Executor.shutdownnow (); }
    }
}

The results are as follows, and the task stops after 2 seconds:

This is the result of commenting out the return comment in a catch block in a task that captures Interruptedexception:

Task continues until end method three: Executorservice.awaittermination (long million, timeunit unit)

This method waits for all tasks to end, or the timeout time to return immediately, and returns True if all tasks are completed, or false

public class Awaittermination {static Class Task implements Runnable {public String name;

        private int time;
            The public Task (String s, int t) {name = S;
        Time = t; public void Run () {for (int i = 0; i < time; ++i) {try {T
                Hread.sleep (1000); The catch (Interruptedexception e) {System.out.println (name + "is Interrup
                    Ted when calculating, would stop ... "); Return  Note that if you do not return, the thread will continue to execute, so the task times out and then the result is processed and then returned} System.out.println ("task" + name + "" +
            (i + 1) + "round");
        } System.out.println ("task" + Name + "finished successfully");
        } public static void Main (string[] args) {Executorservice executor = Executors.newcachedthreadpool ();
        Task task = new Task ("One", 5); Task Task2 = new Task ("Two", 2);
        future<?> Future = executor.submit (Task);
        future<?> Future2 = Executor.submit (TASK2);
        List<future<?>> futures = new arraylist<future<?>> ();
        Futures.add (future);
        Futures.add (Future2); try {if (Executor.awaittermination (3, Timeunit.seconds)) {System.out.println ("task finished"
            );
                else {System.out.println ("Task time out,will terminate");
                    for (future<?> f:futures) {if (!f.isdone ()) {F.cancel (true); catch (Interruptedexception e) {System.out.println (
        "Executor is interrupted");
        finally {Executor.shutdown (); }
    }
}

The

results are as follows:
method Four: Set up a daemon thread, enters upgradeable sleep a period of time, wake up and interrupt the thread it watches

public class Demonthread {static Class Task implements Runnable {private String name;

        private int time;
            The public Task (String s, int t) {name = S;
        Time = t;
        public int GetTime () {return time; public void Run () {for (int i = 0; i < time; ++i) {try {T
                Hread.sleep (1000); The catch (Interruptedexception e) {System.out.println (name + "is Interrup
                    Ted when calculating, would stop ... "); Return  Note that if you do not return, the thread will continue to execute, so the task times out and then the result is processed and then returned} System.out.println ("task" + name + "" +
            (i + 1) + "round");
        } System.out.println ("task" + Name + "finished successfully"); } Static class Daemon implements Runnable {list<runnable> tasks = new Arraylist<runnable> (
    );    private thread thread;

        private int time;
            Public Daemon (thread r, int t) {thread = R;
        Time = t;
        public void AddTask (Runnable r) {Tasks.add (R); @Override public void Run () {while (true) {try {thre
                Ad.sleep (time * 1000);
                catch (Interruptedexception e) {e.printstacktrace ();
            } thread.interrupt ();
        }} public static void Main (string[] args) {Task Task1 = new Task ("One", 5);
        thread T1 = new Thread (TASK1);
        Daemon Daemon = new Daemon (t1, 3);
        Thread daemothread = new thread (daemon);
        Daemothread.setdaemon (TRUE);
        T1.start ();
    Daemothread.start (); }
}

The first step is to monitor multiple tasks with a set in the daemon. Then found that to achieve this function must be in the Guardian task for each monitoring task to open a monitoring task, and can not think of a better way to solve, simply monitor a forget, to later improve it.
The results of the operation are as follows:
method Five: Use Timer/timertask, or other schedule-related classes

Summary: It should be noted that, regardless of either of these methods, the implementation of the principle is after the timeout through the interrupt interrupt the operation of the target thread, so you have to catch the Interruptedexception catch code block return, otherwise the thread will still continue to execute. In addition, the last two methods are essentially the same, both by holding a reference to the target thread and interrupting the target thread at the end of the timer, both of which have the lowest control precision because it uses another thread to monitor the target thread's running time because of the uncertainty of the thread schedule, Another thread is not likely to be executed immediately after a timed end and interrupts the target thread.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.