Sole purpose of using concurrency is to produce scalable and faster program. But always remember, the speed comes after correctness. Your Java program must follow their invariant in all conditions, which it would, if executed in sequential manner. If you is new in concurrent Java programming, then take some time to get familiar yourself with different problem arises Due to concurrent execution of the program e.g. deadlock, race conditions, livelock, starvation etc.
1) Use Local Variables
Always try-to-use local variables instead of creating class or instance variables. Some time, developer use instance variable to save memory and reusing them, because they think creating local variable Eve Ry Time method invoked a lot of memory. One example of this was declaring Collection as member and reusing them by using clear () method. This introduce, a shared state in otherwise stateless class, which was designed for concurrent execution. Like in below code, where execute () method was called by multiple threads, and to implement a new functionality, you need a Temp collection. In original code, aStatic Listwas used and developer ' s intention is to clear this at the end of Execute () method for reuse. He thought that code was safe because of Copyonwritearraylist is thread-safe. What the he failed to realize that, since this method get called by multiple threads, one thread could see data written by other Thread in shared temp List. Synchronization provided by the list are not enough to protect method ' s invariant here.
public class concurrenttask{ private static List temp = Collections.synchronizedlist (new ArrayList ()); @Override public void execute (Message message) { //i need a temporary ArrayList this, use local //list temp = n EW ArrayList (); Add something from Message to List temp.add ("Message.getid ()"); Temp.add ("Message.getcode ()"); Combine ID and code store result back to message temp.clear (),//Let ' s resuse it }}
problem:
One message ' s data would go to the other Message if the multiple thread interleaved. e.g. T1 adds ID from message 1 then T2 adds Id from Message 2, which happens before List get cleared, so one of those mess Age would has corrupted data.
Solution:
1) Add a synchronized block when one thread is Add something to temp list and clear () it. So, the no thread can access List until one is doing with it. This would make, part, single threaded, and reduce overall application performance by that percentage.
2) use a local List instead of a global one. Yes It'll take the few more bytes, but the is free from synchronization and code is much more readable. Also, you should is worrying too much about temporary objects, GC and JIT would take care of that.
This is just one of the those cases, but I personally prefer a local variable rather than a member variable in multi-threading , until its part of design.
2) Prefer immutable Classes
Another and most widely known Java multi-threading best practice are to prefer immutable class. Immutable classes like String, Integer and other wrapper classes greatly simplify writing concurrent code in Java because You don ' t need to worry about there state. Immutable classes reduce amount of synchronization in code. Immutable classes, once created, can not is modified. One of the best example of the java.lang.String, any modification on String e.g. converting it into uppercase, trim or Substring would produce another string object, keeping original string object intact.
3) Minimize locking scope
Any code which is inside lock'll not being executed concurrently and if you have 5% code inside lock than as per Amdahl ' s L Aw, your application performance can not is improved more than times. Main reason of this is those 5% code would always executed sequentially. You can reduce the amount by minimizing scope of locking and try to the only lock critical sections. One of the best example of minimizing scopes of locking is a double checked locking idiom, which works by using volatile vari Able after Java 5 improvements on Java Memory model.
4) Prefer Thread Pool executors instead of Threads
Creating Thread is expensive. If you want a scalable Java application, you need the use thread pool. Apart from cost, managing thread requires lots of boiler-plate code and mixing those with business logic reduces Readabili Ty. Managing threads is a-framework level task and should being left to Java or any proprietary the framework you are using. JDK have a well built, rich and fully tested Thread pool also known as Executor Framework, which should be utilized Wheneve R needed.
5) Prefer synchronization utility over wait notify
This Java multi-threading practice inspires from Java 1.5, which added lot of synchronization utilities like Cycicbariier, Countdownlatch and Sempahore. You should always look to JDK concurrency and synchronization utility, before thinking of wait and notify. It ' s much easier to implement Producer-consumer design with Blockingqueue than by implementing them using wait and notify. See those-links to compare yourself. Also, it ' s much easier to wait for 5 threads using Countdownlatch to complete there task rather than implementing same UTI Lity using wait and notify. Get yourself familiar with Java.util.concurrent package for writing better Java concurrency code.
6) Prefer blockingqueue for Producer-consumer design
This multi-threading and concurrency best practice was related to earlier advice, but I had made it explicitly because of It ' s importance in real world concurrent applications. Many of concurrency problem was based on Producer-consumer design pattern and Blockingqueue was best by NT them in Java. Unlike Exchanger synchronization utility which can be used to implement single producer-consumer design, blocking queue CA n also handle multiple producer and consumers. See producer consumer with Blockingqueue in Java to learn more on this tip.
7) Prefer Concurrent collections over synchronized Collection
As mentioned in my post about Top 5 Concurrent collections in Java, they tend to provide more scalablility and performance than there synchronized counterpart. Concurrenthashmap, which is I guess one of the most popular of all concurrent collection provide much better performance t Han synchronized HashMap or Hashtable if number of reader thread outnumber writers. Another advantage of Concurrent collections is that, they is built using new locking mechanism provided by Lock INTERFAC E and better poised to take advantage of native concurrency construct provided by underlying hardware and JVM. In the same line, consider using copyonwritearraylist on place of synchronized list, if list was mostly for reading purpose With rare updates.
8) Use Semaphore to create bounds
In order to build a reliable and stable system, you must has bounds on resources like database, file system, sockets etc. In no situation, your code create or use infinite number of resources. Semaphore is a good choice to has a limit on expensive resource like database connection, by the the-the-the-the-the-the-same-to-yo ur Connection pool. Semaphore is very helpful to creating bounds and blocking thread ifresource are not available. Can follow this tutorial to learn "how to" use the use of Semaphore in Java.
9) Prefer synchronized block over synchronized method
THIS  Java multi-threading Best Practice is a extension of earlier best practice about minimizing scope of locking. using synchronized block is one-to-reduce scope of lock and it also allow-you-to-lock on object other than "This", which represent the current object. Today, your first choice should be atomic variable, followed by volatile variable if your synchronization requirement are S Atisfied by using them. If you need mutual exclusion you can consider using reentrantlock followed by plain old synchronized Keywor D. If you is new to concurrency and is writing code for high frequency trading or any other mission critical application , stick with synchronized keyword because it much safer and easy to use. If you is new to Lock interface, see my tutorial how to use Lock in multi-threaded Java program for step by Ste P Guide.
Avoid Using Static variables
As shown in first multi-threading best practice, static variables can create lots of issues during concurrent execution. If you happen to use static variable, consider it making static final constants and if static variables is used to store Collections like List or Map and consider using only read only collections. If you is thinking of reusing Collection to save memory, please see the example in first best practice-Learn how Stati c variables can cause problem in concurrent programs.
One ) Prefer Lock over synchronized keyword
This was a bonus multi-threading best practice, but it's double edge sword at same time. Lock interface is powerful but every power comes with responsibility. Different locks for Read and write operation allows to build scalable data structures like Concurrenthashmap, but it also Require lot of care during coding. Unlike synchronized keyword, thread doesn ' t release lock automatically. You need to call unlock () method to release a lock and the best practice are to call it on the finally block to ensure release in a ll conditions. Here is a idiom to use explicitly lock in Java:
Lock.lock (); try { //do something ...} finally { lock.unlock ();}
By the the-the-this-article is-in-line with ten JDBC best practices and Ten code comments best practices, if you haven ' t read t Hem already, you may find them worth reading. As some of agree that there is no end of the best practices, It evolves and get popular with time. If you guys has any advice, experience, which can help any one writing concurrent program in Java, please share.
That's all on the This list ofJava multithreading and concurrency best practices. Once again, reading Concurrency practice in Java and effective Java is worth reading again and again. Also developing a sense for concurrent execution by doing code review helps a IoT on visualizing problem during developmen T. on closing note, let us know "what's best practices you follow while writing concurrent applications in Java?"
Read More:http://javarevisited.blogspot.com/2015/05/top-10-java-multithreading-and.html#ixzz3uwid7ok7
Java Multithreading Coding considerations