Java Multithreading concurrency Best Practices __java

Source: Internet
Author: User
Tags semaphore static class

Writing concurrent code is more difficult, although the Java language provides a lot of synchronization and concurrency support, but ultimately it takes a person's diligence and expertise to write Java concurrency code without bugs. Java multithreaded concurrency best practices are a good set of practical ideas that help you quickly develop high quality concurrent code. If you are a novice, you need to be familiar with some basic concepts, and then read this article will be more targeted.

1. Use local variables

You should always use a local variable instead of creating a class or instance variable, and typically, developers using object instances as variables can save memory and can be reused because they think it consumes a lot of memory each time you create a local variable in a method. The Execute () method of the following code is called by multithreading, in order to implement a new function, you need a temporary set collection, which is used as a static class variable in the code, and then clears the collection at the end of the Execute method for reuse. The person who wrote this code might think it's thread-safe, because copyonwritearraylist is thread-safe, but he doesn't realize that this method execute () is called by multiple threads, and that one thread in a multiple-thread can see the temporary data of another thread, Even using collections.synchronizedlist does not guarantee the logical invariance within the Execute () method: This is a temporary collection that can only be visible within each thread's execution and not exposed to other threads.

2. Using Immutable classes

Immutable classes such as String integer once created and no longer changed, immutable classes can reduce the number of synchronizations needed in your code.

3. Scope of minimizing locks

Any code in the lock will not be executed concurrently. If you have 5% code in the lock, then according to Amdahl's, your application image can not be increased by more than 20 times times, because the lock in the code only sequential execution, reduce the scope of the lock, locking and unlocking the code between the less the better.

4. Use thread pool Excutor instead of direct new thread to perform

The cost of creating a thread is expensive, and if you want to get a scalable Java application, you need to use a thread pool to manage threads. JDK provides a variety of threadpool thread pools and executor.

5. Rather than using a thread's wait notify to sync with a wet suit

Since Java 1.5 has increased the need for synchronization tools such as Cycicbariier, Countdownlatch, and Sempahore, you should prioritize these synchronization tools instead of thinking about how to use thread wait and notify, Achieving production-consumption through blockingqueue is much better than using threads of wait and notify, or you can use Countdownlatch to implement multiple thread waits:

Import Java.util.Date;

Import Java.util.concurrent.CountDownLatch;

Import Java.util.logging.Level;

 

Import Java.util.logging.Logger; /** * Java program to demonstrate how to use Countdownlatch in Java. Countdownlatch is * Useful if your want to start main processing thread once it dependency is completed * as Illustrat  Ed in this countdownlatch Example * * @author javin Paul */public class Countdownlatchdemo {public static

       void Main (String args[]) {final Countdownlatch latch = new Countdownlatch (3);

       Thread cacheservice = new Thread (New Service ("Cacheservice", 1000, latch));

       Thread alertservice = new Thread (New Service ("Alertservice", 1000, latch));

     

       Thread validationservice = new Thread (New Service ("Validationservice", 1000, latch)); Cacheservice.start (); Separate thread would initialize Cacheservice Alertservice.start (); Another thread for Alertservice initialization Validationservice.start ();

       Application should not start processing the any thread until the all service are up//and ready to do there job. Countdown latch is idle choice here, main thread would start with count 3//And wait until count reaches Zer O. Each thread once up and read'll do//a count down.

     

       This would ensure that main thread isn't started processing//until all services are up.  The count is 3 since we have 3 Threads (Services) try{latch.await (); Main thread is waiting on Countdownlatch to finish System.out.println ("All services are up, application is

       Starting now ");

       }catch (Interruptedexception IE) {ie.printstacktrace ();

 }}/** * Service class which is executed by Thread using Countdownlatch synchronizer.

    * * Class Service implements runnable{private final String name;

    private final int timetostart; Private Final COuntdownlatch latch;

        The public Service (String name, int timetostart, Countdownlatch latch) {this.name = name;

        This.timetostart = Timetostart;

    This.latch = latch;

        @Override public void Run () {try {thread.sleep (Timetostart);

        The catch (Interruptedexception ex) {Logger.getlogger (Service.class.getName ()). log (Level.severe, NULL, ex);

        } System.out.println (name + "is"); Latch.countdown (); Reduce count of Countdownlatch by 1}}

Output:

Validationservice is up

Alertservice is up

Cacheservice is up

All services are up, application are starting now

6. Using Blockingqueue to achieve production-consumption patterns

Most concurrency problems can be implemented using Producer-consumer production-consumption design, while Blockingqueue is the best way to do it, blocking queues that can handle not only individual production individual consumption, but also multiple production and consumption. The following code:

Import Java.util.concurrent.BlockingQueue;

Import Java.util.concurrent.LinkedBlockingQueue;

Import Java.util.logging.Level;

 

Import Java.util.logging.Logger;

     public class Producerconsumerpattern {public static void main (String args[]) {//creating Shared object

 

     Blockingqueue sharedqueue = new Linkedblockingqueue ();

     Creating Producer and Consumer thread thread prodthread = new Thread (new Producer (Sharedqueue));

 

     Thread consthread = new Thread (new Consumer (Sharedqueue));

     Starting producer and Consumer thread Prodthread.start ();

    Consthread.start (); }//producer class in Java class Producer implements Runnable {private final blockingqueue Sharedqueue

 

    ;

    Public Producer (Blockingqueue sharedqueue) {this.sharedqueue = Sharedqueue; @Override public void Run () {for (int i=0; i<10; i++) {try {Syst Em.out.println ("produced: "+ i);

            Sharedqueue.put (i); The catch (Interruptedexception ex) {Logger.getlogger (Producer.class.getName ()). log (Level.severe, NULL, EX

            ); {}}}//consumer class in Java class Consumer implements runnable{private final Blocking

 

    Queue Sharedqueue;

    Public Consumer (Blockingqueue sharedqueue) {this.sharedqueue = Sharedqueue; @Override public void Run () {while (true) {try {System.out.println (

            "Consumed:" + sharedqueue.take ()); The catch (Interruptedexception ex) {Logger.getlogger (Consumer.class.getName ()). log (Level.severe, NULL, EX

            ); }

        }

    }

 

 

}

Output:

produced:0

Produced:1

consumed:0

Produced:2

Consumed:1

Produced:3

Consumed:2

Produced:4

Consumed:3

Produced:5

Consumed:4

Produced:6

Consumed:5

Produced:7

Consumed:6

Produced:8

Consumed:7

Produced:9

Consumed:8

Consumed:9

7. Use concurrent collection collection instead of a synchronized lock

Java provides concurrenthashmap copyonwritearraylist and Copyonwritearrayset as well as Blockingqueue Deque and Blockingdeque Five concurrent sets, prefer to use these sets, and do not use the collections.synchronizedlist such as a set of synchronized locks, copyonwritearraylist suitable for the main reading rarely write occasions, Concurrenthashmap is more commonly used concurrent collections

8. Use semaphore to create a bounded

In order to establish a reliable and stable system, the database file system and sockets and other resources must be bounded bound,semaphore is a can limit the cost of these resources, if a resource can not, use semaphore can be the lowest cost blocking thread waiting:

Import Java.util.concurrent.Semaphore;
  
    public class Semaphoretest {semaphore binary = new semaphore (1);
        public static void Main (String args[]) {final semaphoretest test = new Semaphoretest (); 
            New Thread () {@Override public void run () {test.mutualexclusion ();
      
        }}.start (); 
            New Thread () {@Override public void run () {test.mutualexclusion ();
      
    }}.start ();

            private void Mutualexclusion () {try {binary.acquire (); Mutual Exclusive Region System.out.println (Thread.CurrentThread () getName () + "inside Mutual exclusive-Regi
            On ");

        Thread.Sleep (1000);
        catch (interruptedexception i.e.) {ie.printstacktrace ();
            finally {binary.release (); System.out.println (Thread.CurrentThread (). GetName () + "Outside of MutuAl exclusive region ");
 }
    } 
  
}

Output:
Thread-0 inside Mutual Exclusive region
Thread-0 outside of Mutual exclusive region
Thread-1 inside Mutual Exclusive region
Thread-1 outside of Mutual exclusive region

9. Prefer to use synchronized code block, and do not use the method of adding synchronization

Using synchronized to synchronize blocks of code locks only one object without locking the current whole method, and if you change the field of a common variable or class, first select the atomic variable and then use volatile. If you need a mutex, you can consider using Reentrantlock

10. Avoid using static variables

Static variables create a lot of problems in a concurrent execution environment, and if you have to use a static variable to call it a final constant, consider using a read-only collection if you want to save the collection collection.

11. Prefer to use locks rather than synchronized synchronization keywords

Lock lock interface is very powerful, fine-grained, for read and write operations have different locks, so that can easily expand scaling, and synchronized will not automatically release locks, if you use Lock () lock, you can use unlock unlock:

Lock.lock ();

try {

 //do something ...

} finally {

 lock.unlock ();

 }

Turn from: http://www.jdon.com/concurrent/java-multithreading-best-pratices.html

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.