Java Magazine, September/October 2016
ORACLE COM JAVAMAGAZINE SEPTEMBER OCTOBER 2016 62 fix this use of method references anyway Further the new keyword should follow the double colon in a method reference Option E is just wrong Question 3 The correct answer is option E This question investigates the concurrent mode of stream processing and the rules that ensure it runs correctly and in a thread safe fashion A common recommendation is that stream processing if theres any chance of the stream being executed in concurrent mode should not mutate any shared data Such an approach is a great way to ensure that concurrency problems do not arise However the actual rule is somewhat less restrictive If shared state will be modified then the programmer must ensure that those modifications are safe In this case using a LongAdder would achieve this goal and option E is the correct answer Interestingly this situation could also be served by using the AtomicInteger but the LongAdder was deliberately created to support many concurrent mutations in a scenario where relatively few reads are performed Both would be functionally correct but the adder will be more scalable Lets look at the wrong answers and see what might be interesting about those First why doesnt this code compile The variable total is a method local variable and for that to be used in an enclosed lambda it must be final or efectively final Consequently because it is not final and it cannot be because it is mutated the code as it stands will not compile This is why option A is incorrect Option B looks tempting and in many cases it would probably work First it uses an array of one int to accumulate the total This successfully sidesteps the problem of a final variable because the variable is a pointer to the array and is indeed now effectively final However even though the call to parallel was also removed from the code the stream was received as an argument to the method so its not safe to assume that the stream is now running sequentially It could have been set to parallel by the caller In that situation the code remains unsafe from a concurrency perspective So option B is incorrect because the behavior would still not be reliable Option C is unworkable Integer objects are immutable and given that total must be effectively final theres really no way that such a suggestion could result in correct counting Option D might seem tempting Presumably the idea is that if the mutation operation performed by peek can be performed sequentially there will be no concurrency issue with respect to the updates to total Unfortunately this fails for two reasons first and most compellingly the option still doesnt compile because total is still not effectively final Second and also important is the fact that streams dont shift between parallel and serial modes along their length The whole stream from end to end is either parallel or sequential Therefore moving the call to parallel later in the chain changes absolutely nothing For both these reasons option D is also incorrect Question 4 The correct answer is option B Theres quite a lot of code in this question That is unusual in the actual certification exam but it does happen This question tests one specific piece of understanding but it introduces a number of interesting side issues for discussion as distractions The code does not compile simply because the get method on a Future object throws checked exceptions In fact the documentation declares three exceptions two of which are checked The unchecked exception is Cancellation Exception which indicates that the job was canceled Therefore trying to get its result is meaningless The checked exceptions are InterruptedException and Execution Exception An InterruptedException results if the get method which will block if the job hasnt finished yet is interrupted while waiting An ExecutionException arises if the job itself throws an exception the cause of the Execution Exception is the actual exception thrown by the job
You must have JavaScript enabled to view digital editions.