Java review several small issues collection

Source: Internet
Author: User
Tags delete key google guava

1 improper use of thread pool

Our dispatch system needs to assign a bunch of members to the appropriate personnel to process, as shown in the following pseudo-code:

public void Dispatch () {        while (true) {            list<member> memberlist = Getunassignedmemberlist ();//Get All Unassigned Members For            (Member each:memberlist) {                 singledispatch (each);  Assign each member the appropriate person to handle            }            try {                thread.sleep (1000);//Hibernate after 1 seconds to continue allocation            } catch (Interruptedexception e) {            }        }    }

In order to increase the speed of distribution, we intend to use multi-threaded allocation. At first, Newcachedthreadpool was used.

private static  Executorservice executor = Executors.newcachedthreadpool ();    public void Dispatch () {        while (true) {            list<member> memberlist = Getunassignedmemberlist ();//Get All Unassigned Members For            (final Member each:memberlist) {                executor.submit (new Runnable () {                    @Override public                    void Run () {
   singledispatch (each);  Assign the appropriate person to each member                    }                );            try {                thread.sleep (1000);//Hibernate after 1 seconds to continue allocation            } catch (Interruptedexception e) {            }}    }

At the time of the test, load soared high, and many threads were opened through the catch stack discovery. The reason is: Newcachedthreadpool maximum number of threads is the maximum value of an integer, each commit a task, if there is no threading, then a new thread is generated. When our For loop commits a task, it opens up hundreds of threads and the application crashes immediately.
Now that we have found the reason, we will adjust the thread pool to newfixedthreadpool, here we can set the maximum number of threads to 4, the queue length is the maximum value of the integer type.

private static Executorservice executor = Executors.newfixedthreadpool (4);

However, the measurement and detection of new problems, the line constructor queue length is increasing, and the allocation of the constant exception thrown (the exception information for the member has been assigned).
The reason: when there are more unassigned members, it may take up to 5 seconds to allocate However, Executor.submit is an asynchronous operation, when dormant for 1 seconds, immediately into the next loop, the queue will be inserted into the duplicate members, which will cause the queue length is growing, in addition, will cause 1 members are allocated, and continue to be assigned, resulting in an exception.
Workaround: Use the InvokeAll synchronization statement, which means that subsequent statements are executed only after the commit task has been executed.

public void Dispatch () {while        (true) {            list<callable<string>> tasks = new arraylist<callable <String>> ();            list<member> memberlist = Getunassignedmemberlist (); Get all Unassigned members for            (final Member each:memberlist) {                tasks.add (new callable<string> () {                    @Override Public                    String Call () {                        singledispatch (each);                        return "OK";}}                );            try {                Executor.invokeall (tasks, 480, timeunit.seconds);//If 8 minutes have not been completed, the time-out is renewed (robustness guaranteed)            }catch (Exception e) { c15/>}            try {                thread.sleep (1000);//Hibernate after 1 seconds to continue allocation            } catch (Interruptedexception e) {            }}    }
2 NPE (java.lang.NullPointerException) 2.1 Case 1
if (case.gettype () = = case.type_self) {            ...}

When this code throws the NPE, it is intuitively assumed that case is null, and later the log finds that the case is not NULL, whereas the Case.gettype () return value type is integer, which is null.
Finally, it was found that case.type_self returned the type int, while Case.gettype () was a null,null and an int compared to the NPE.

The weird thing about this problem is that we intuitively think that case.type_self is an integer, so it takes some time to troubleshoot the problem, so a suggestion that this constant, such as case.type_self, is changed to integer, avoids the problem.

2.2 Scenario 2
Integer Leftnum = (null! = Leftnummap &&!leftnummap.isempty ())? Leftnummap.get (Stat.getdepartmentid ()): 0;

This also throws the NPE, we have been troubleshooting for more than half an hour, baffled its solution, and later looked at the class file found the reason.
Suppose our code is:

map<string, integer> leftnummap = new hashmap<string, integer> ();        Integer Leftnum = (null! = Leftnummap &&!leftnummap.isempty ())? Leftnummap.get ("Test"): 0;

The post-compilation code is as follows:

HashMap Leftnummap = new HashMap ();        Integer leftnum = integer.valueof (null! = Leftnummap &&!leftnummap.isempty ()? ( (Integer) leftnummap.get ("Test")). Intvalue (): 0);

Why is that? " Do you really use the three-mesh operator in Java?" "is explained in the article. The syntax specification for the three-mesh operator is written like this: If one of the second and third operands is of the primitive type T, and the type of the and the other are the ResU Lt of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

In a nutshell: When the second, third operand is an object of the base type, the object is disassembled as the base type.
So, the result is: because the three-mesh operator is used, and the second, third-digit operand is a primitive type, one is an object. Therefore, the object is unboxing, because the object is null, so when the unboxing process called Null.intvalue (), the time of the report to the NPE.
The workaround is simple: 1) Either use the if else directly without the trinocular operator, be simple and reliable, 2) or change the three-mesh operator operand to an object.

Integer Leftnum = (null! = Leftnummap &&!leftnummap.isempty ())? Leftnummap.get (Stat.getdepartmentid ()): integer.valueof (0);
3 map<k, list<v>> used wrong

The following data structures are often present in our code, such as the key is the category, and value is a list,list that stores the statistical data for each subclass of the class.

map<string,list<myclass>> Myclasslistmap = new Hashmap<string,list<myclass>> ()

This is often the case when we insert this data structure:

void Putmyobject (String key, Object value) {    list<object> myclasslist = Myclasslistmap.get (key);    if (myclasslist = = null) {        myclasslist = new arraylist<object> ();        Myclasslistmap.put (key,myclasslist);    }    Myclasslist.add (value);}

When we want to check whether an object in the list exists, or delete an object, it takes more code to traverse the entire data structure.
This code not only creates obstacles to readability, but also increases the probability that people will go wrong, such as when we implement Putmyobject in complex business logic, we miss a sentence:

Myclasslistmap.put (key,myclasslist);

As a result, it took a lot of time to discover the problem.
Of course, careful testing and code review to avoid similar problems, but is there a way to help us avoid such problems from the technology and save code to improve code readability?
We recommend that you use Google Guava package, which provides MULTIMAP data structure, the use of the following, very concise and clear, there will be no chance to make mistakes.

multimap<string, string> mymultimap = Arraylistmultimap.create ();        Mymultimap.put ("Ladies", "underwear");        Mymultimap.put ("Ladies", "down Jacket");        Mymultimap.put ("Ladies", "windbreaker");        Mymultimap.put ("mens", "leather Jacket");        Get key "ladies" corresponding to list        collection<string> womendresslist = Mymultimap.get ("ladies");        Delete key "ladies" corresponding list in the "Down Jacket"        mymultimap.remove ("Ladies", "down Jacket");

Java review several small issues collection

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.