Comparable interface implemented by Delayqueue

Source: Internet
Author: User
Tags comparable sorted by name static class

Delayqueue comparable interface and delayed interface off-thread pool digression-Static inner class

Delayqueue

Delayqueue is a kind of implementation class of JDK to Blockingqueue interface. For the introduction of Delayqueue, you can refer to a very good article. comparable interface and delayed interface

The elements saved by the Delayqueue queue must implement the delayed interface, while the delayed interface implements the comparable interface.

Need to understand the meaning of the delayed interface and the comparable interface. See the comments in the student class for details.

/**
 * Delayqueue element must implement {@link delayed} interface (also implements {@link comparable}) interface
 * {@link delayed#getdelay (timeunit)} Determines whether the element can be removed
 * {@link Comparable#compareto (Object) determines the order in which elements are arranged in the queue, and when many elements can be taken out, in this order.
 

You can learn Delayqueue with the following examples:

Package example.concurrency.blockingqueue;
Import Java.util.Random;

Import java.util.concurrent.*;

    /** * @author Liuhaibo on 2017/11/28/public class Usageofdelayqueue {private static final int student_num = 10;
        public static void Main (string[] args) throws Interruptedexception {Random r = new Random ();
        delayqueue<student> students = new delayqueue<> ();

        To run Student executorservice exec = Executors.newfixedthreadpool (student_num);
        for (int i = 0; i < Student_num i++) {students.put (New STUDENT ("STUDENT" + I, 3000 + r.nextint (5000)));  }//Start take object from Delayqueue while (!students.isempty ()) {//Take a Student
        and execute since it ' s Runnable exec.execute (Students.take ());
    } exec.shutdown (); The Elements of/** * Delayqueue must implement the {@link delayed} interface (while also implementing the {@link comparable}) interface * {@link delayed#getdelay (timeunit)} Determines whether an element canRemoved * {@link Comparable#compareto (Object)} determines the order of elements in the queue, and when many elements can be taken out, in this order of the * * private static Class Stu
        Dent implements Runnable, delayed {private String name;
        Assigned by Random Private long costtime;

        Time to finish private long finishedtime;
            Student (String name, long costtime) {this.name = name;
            This.costtime = Costtime;
        Finishedtime = Costtime + System.currenttimemillis (); @Override public void Run () {System.out.println (name +) finished.
        Time used: "+ costtime +" MS ");
         }/** * To judge the time after which object can is take out of the delay queue * @param unit * @return */@Override public long Getdelay (timeunit unit) {return (finished
        Time-system.currenttimemillis ());
 }/** * To sort object in the delay queue        * @param o * @return * * @Override public int compareTo (delayed o) {
            Student other = (Student) o; Return costtime >= other.costtime?
1:-1;
        Return Name.compareto (Other.name); }

    }
}

One possible output result is as follows:

Student3 finished. Time Used:3087ms
Student5 finished. Time Used:3334ms
Student8 finished. Time used:3745ms
Student9 finished. Time used:4215ms
Student1 finished. Time Used:4309ms
Student6 finished. Time Used:4773ms
Student7 finished. Time Used:5761ms
Student2 finished. Time Used:7151ms
Student4 finished. Time Used:7243ms
Student0 finished. Time used:7855ms

Delayqueue first sorts all the elements according to the comparable interface, in general, we sort by the priority of the element expiration time . Here, that is, sort by costtime, making costtime small in front of the queue. Because Getdelay () determines whether the element can be out of the column, so Finishedtime small (that is, costtime small) earlier can have the qualifying. So, in the end, an ideal scenario is achieved: the elements at the beginning of the queue have the ability to qualify earlier, allowing the entire queue to execute at the fastest possible time. Personally, this is also the intention of delayqueue to introduce the comparable interface.

In contrast, if we modify the Student#compareto (delayed O) method so that it is sorted by name (that is, the line of code that is commented out), one possible output is as follows:

Student0 finished. Time Used:7503ms
Student1 finished. Time Used:5281ms
Student2 finished. Time Used:3718ms
Student3 finished. Time Used:3322ms
Student4 finished. Time Used:3281ms
Student5 finished. Time Used:4981ms
Student6 finished. Time Used:3757ms
Student7 finished. Time Used:5313ms
Student8 finished. Time used:6080ms
Student9 finished. Time used:3112ms

As you can see, the program takes the object out of the Delayqueue and executes it in the order of student name. This is obviously much slower than sorting by Costtime. The reason for this, we in Delayqueue to student objects in accordance with the name of student, Student0 need 7503MS to have a team qualification, and STUDENT0~9 can have a team than Studnet0 earlier qualifications, However, because Blockingqueue's take () method is to take the first element of the team, if the team head can not be out, then all the student can only wait in the queue, can not be executed. digression-thread pool

It is worth mentioning that the thread pool in the main function has little to do with the speed at which the program runs. Because even if you open 10 threads, you cannot take out any of the student when the team head student does not qualify for the team. And every time once the student is taken out, its execution task is to print a word, the moment is complete, and will not cause a thread to run for a while.

To see the effect of the thread pool, we will student the run () method to block 1s at execution time, and in the main () method to record the total execution of the program, and then compare the thread pool and single thread effect. The revised procedure is as follows:

Package example.concurrency.blockingqueue;
Import Java.util.Random;

Import java.util.concurrent.*;

    /** * @author Liuhaibo on 2017/11/28/public class Usageofdelayqueue {private static final int student_num = 10; 

        public static void Main (string[] args) throws Interruptedexception {Long start = System.currenttimemillis ();
        Random r = new Random ();
        delayqueue<student> students = new delayqueue<> ();
To run Student executorservice service = Executors.newfixedthreadpool (student_num);

        Executorservice service = Executors.newsinglethreadexecutor ();
        for (int i = 0; i < Student_num i++) {students.put (New STUDENT ("STUDENT" + I, + r.nextint (3000)));  }//Start take object from Delayqueue while (!students.isempty ()) {//Take a Student
        and execute since it ' s Runnable service.execute (Students.take ());

  } service.shutdown ();      Service.awaittermination (1, timeunit.hours);
        Long stop = System.currenttimemillis ();
    SYSTEM.OUT.PRINTLN ("Total time used:" + (Stop-start) + "Ms."); The Elements of/** * Delayqueue must implement the {@link delayed} interface (while also implementing the {@link comparable}) interface * {@link delayed#getdelay (timeunit)} Determines whether an element can be removed * {@link Comparable#compareto (Object) determines the order in which elements are queued, and when many elements can be taken out, it is done in this order/private static
        Class Student implements Runnable, delayed {private String name;
        Assigned by Random Private long costtime;

        Time to finish private long finishedtime;
            Student (String name, long costtime) {this.name = name;
            This.costtime = Costtime;
        Finishedtime = Costtime + System.currenttimemillis (); @Override public void Run () {System.out.println (name +) finished.

            Time used: "+ costtime +" MS ");
              Synchronized (this) {  try {wait (1000);
                catch (Interruptedexception e) {e.printstacktrace ();
        } System.out.println (name + "done~");
         }/** * To judge the time after which object can is take out of the delay queue * @param unit * @return */@Override public long Getdelay (timeunit unit) {return (finished
        Time-system.currenttimemillis ()); }/** * To sort object in the delay queue * @param o * @return * * * @Ov
            Erride public int compareTo (delayed o) {Student other = (Student) o; Return costtime >= other.costtime?
1:-1;
        Return Name.compareto (Other.name); }

    }
}

One possible multithreaded implementation is as follows:

Student9 finished. Time used:2570ms
Student8 finished. Time used:2695ms
Student1 finished. Time Used:3252ms
Student6 finished. Time Used:3361ms
Student3 finished. Time used:3455ms
Student5 finished. Time Used:3469ms
Student9 done~
Student8 done~ Student7
. Time Used:4236ms
Student1 done~
Student6 done~
Student3 done~
Student5 done~
Student2 Finished. Time Used:4539ms
Student0 finished. Time Used:4771ms
Student4 finished. Time Used:4979ms
Student7 done~
Student2 done~ Student0 done~ Student4 done~ total time
used : 5983ms.

You can see that when the first thread executes STUDENT9, the second thread takes out and executes the element Student8 of the current team head, and so on, the program is executed in total 5.983s.

Look at one possible single-threaded execution (enable the Executorservice service that is commented out by the main function = Executors.newsinglethreadexecutor ()):

Student4 finished. Time used:2300ms
Student4 done~
Student1 finished. Time Used:2784ms
Student1 done~
Student5 finished. Time Used:3699ms
Student5 done~
Student0 finished. Time used:3720ms
Student0 done~
Student3 finished. Time used:3901ms
Student3 done~
Student8 finished. Time used:3965ms
Student8 done~
Student7 finished. Time Used:4257ms
Student7 done~
Student2 finished. Time Used:4316ms
Student2 done~
Student9 finished. Time Used:4367ms
Student9 done~
Student6 finished. Time used:4705ms
Student6 done~ total time
used:12306ms.

Visible, after the STUDENT4 team, the thread will execute it, before you take out the current team head Student1, and execution completed, and so on. The final program takes 12.306s.

The benefits of multithreading can only be reflected when tasks that need to be performed are more time-consuming. digression-Static inner class

The last sentence added: Student as the inner class of the Usageofdelayqueue class, it needs to be set static, that is, a static inner class, or it will report a compile-time error: "Non-static variable this cannot to be referenced From ' A static context '.

Because we used synchronized to lock the this object in student. However, in the main function, we do not instantiate the Usageofdelayqueue object, all non-static inner classes contain references to external classes (or pointers to external classes), and instances of the inner class are naturally impossible if an instance of the outer class does not exist, This also has no student object to refer to, so it will be an error.

If you set student as a static inner class, you do not include a reference to the external class, so you do not need the external class to exist or you can instantiate the static inner class. So in general, internal classes exist in the form of static internal classes.

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.