Multithreading security for Java, Reentrantlock and synchronized locks

Source: Internet
Author: User

Objective

Multithreading in general is a very large module, so although I wanted to write but always feel that there is no understanding of the place, after a period of time to learn, finally a little feel, write down essays here.

Multithreading Security issues # #:
 首先和大家讨论一下多线程为什么会不安全,大家先看下面的程序。
/** - @author lw  */public class Test extends Thread{    public void run()    {           for(int i=1;i<=10;i++)        {            System.out.println(i);        }    }    public static void main(String args[])    {        Test t1=new Test();        Test t2=new Test();        Test t3=new Test();        Test t4=new Test();        t1.start();         t2.start();        t3.start();        t4.start();    }

The above program basically means to create a new four threads, each of the operations of the thread is output 1-10, supposedly should be in the thread boot order output, but in fact not. <--12345678112345678910234567891091012345678910--> This is the result of the output. Threads are not executed sequentially because of thread preemption. When the thread executes halfway, the output to 8 is preempted by other threads, and the other threads continue to output.

What is the problem with this concurrency? Let's look at the code below.

/** - @author lw -  */public class Test extends Thread{    static int temp=1;    public void run()    {           temp++;        System.out.println(temp);    }    public static void main(String args[])    {        Test t1=new Test();        Test t2=new Test();        Test t3=new Test();        Test t4=new Test();        t1.start();         t2.start();        t3.start();        t4.start();    }}

You can basically define a static shaping variable, and then each thread can add 1 to the variable,
First the static variable is shared globally, and every thread can manipulate the variable, and the problem is here. If there is a thread 1 run, and then read into the variable is 1, this time the thread 2 preemption, and then the variable is Gay operation, then the thread 1 continues to run, but the variable is now 2, thread 1 read is indeed the previous 1, after the addition of 2, there is a problem. This problem we call the threads out of sync, because the operations between threads are invisible to one another. Below, let's go into a bit more about why.

Why threads are out of sync

Threads are out of sync, essentially because of the cache area of each thread. Each thread will have its own buffer after it is created, and the variables in main memory will be added to the cache and then manipulated in order to avoid the main memory accesses too frequently, which can speed up the execution of threads (similar to cache). But the problem is that each thread is not visible between the buffers, if the load is the same variable in main memory, the changes are made, there will be a thread out of sync problem.

Out-of-sync strategy

OK, the above is the cushion, the following is the focus, how to solve the thread synchronization problem. Java gives the concept of lock. The so-called lock image a little understanding is that a thread is using a resource like a person into a door, if not locked, others will come in, but if the lock, it means that the resource is exclusive to this thread, and must be exited to be used by other threads. What we commonly use is the synchronized lock, also called the synchronous lock. Let's look at the effect of this lock first.

/** * @author lw * */public class Test extends Thread{    String lo="";    public void run()    {           synchronized(lo)        {            for(int i=1;i<=10;i++)            {                System.out.println(i);            }        }    }    public static void main(String args[])    {        Test t1=new Test();        Test t2=new Test();        Test t3=new Test();        Test t4=new Test();        t1.start();         t2.start();        t3.start()        t4.start();    }}

After the above synchronization, the thread can run sequentially because, after the first thread starts, he gets a lock on the variable lo, executes the following block of code, and the other thread waits for the lock to be in a blocking state until the first thread releases the lock and the other threads compete. Then the thread that gets the lock continues the code block, so that the asynchronous between the threads is guaranteed, and then we need to know why the lock can be synchronized.

How synchronized is implemented in sync

Well, actually very simple, the more witty reader may have guessed that he actually makes the cache between the various threads invalid, and then the thread to get the variable when it needs to read and write in main memory, this time the operation of the variable is visible between the various threads, and then the operation is finished and then refresh its buffers, Hahaha is not very simple ...

Synchronized things to be aware of

It is important to note that the target of the synchronized lock is the object, not the code block. This is a beginner's easy access to the misunderstanding. Some people think that as long as the synchronized inside the operation must not be a problem, but when you think of the fact that you are already cold. Take a look at the following code.

/** * @author lw * */public class Test extends Thread{    String lo=new String();    public void run()    {           synchronized(lo)        {            for(int i=1;i<=10;i++)            {                System.out.println(i);            }        }    }    public static void main(String args[])    {        Test t1=new Test();        Test t2=new Test();        Test t3=new Test();        Test t4=new Test();        t1.start();         t2.start();        t3.start();        t4.start();    }}

It does not look much different from the above, but the attentive reader will find that a row has become a string lo=new string (); This time the lock does not make any sense, because each thread of this object will be new, that is, each thread will get one, so it does not work at all. Perhaps the poor base of the reunion asked before the string lo= ""; why, because each lo will point to the Chang (constant pool here do not unfold, hand to waste. Do not know can Baidu a bit) in the same object, so each thread is still pointing to the same section of main memory, the lock will work. Do you think synchonized is already perfect, no no no no more perfect, Rentrantlock shiny debut!!! (Typing is so tiring ....) #==)

Reentrantlock

First we discuss the shortcomings of synchonized. One is inflexible, the synchonized must be locked after the code block to release the lock, and then be obtained by other threads. So what if the thread that gets to the lock executes for a very long time, and the other threads are not stuck here, then what if there is a thread that is angry and doesn't want to wait? Sorry no, we need to wait all the time. On the other hand, the release sequence of the synchronization lock is also very fixed, must be locked in the reverse order, very not handsome and so on ... But our reentrantlock is not the same, not much to say first read the code.

/** * @author lw * */public class Test extends Thread{    private static ReentrantLock lock =new ReentrantLock();    public void run()    {           try{            lock.lock();            for(int i=1;i<=10;i++)            {                System.out.println(i);            }        }        finally        {            lock.unlock();        }    }    public static void main(String args[])    {        Test t1=new Test();        Test t2=new Test();        Test t3=new Test();        Test t4=new Test();        t1.start();         t2.start();        t3.start();        t4.start();    }}

Above we can see that the Reentrantlock object is declared with only a call to the lock method can be directly locked, and release the lock requires the unlock method. This is very flexible, do not need to end the code block and release, there is Reentrantlock is interruptible, if the waiting thread does not want to wait, say, interrupt off, in addition, Reentrantlock can be set as pessimistic lock and optimistic lock, And synchonized is the default pessimistic lock, not change, not flexible. Therefore, the reentrantlock is more flexible and changeable. But everyone in use must remember unlock, it is best to write in finally inside to prevent forgetting, otherwise it will cause other threads to block.

Multi-Threading is a very large knowledge block, the above is the author's own study after the summary induction, there are a lot of not involved, in addition to share the content if there are improper hope that we have a lot of mistakes, common progress ~

Next stage Notice

RADIUS cache

Multithreading security for Java, Reentrantlock and synchronized locks

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.