Using Reentrantlock instead of synchronized keyword primitives in Java concurrency programming

Source: Internet
Author: User
Tags finally block

In the Concurrent Concurrency Library package introduced by Java 5, the Reentrantlock can be re-entered as a synchronous lock to replace the SYNCHRONIZED keyword primitives and provide better performance and more powerful functionality. The way to use it is simple:

Public final Reentrantlock lock=new Reentrantlock ();

......

try {

Lock.lock ();

Go to sync Content

....

} finally {

Lock.unlock (); Must be unlocked in the finally block, or it will remain locked in the event of an exception and no unlock is performed.

}

Synchronized primitives and Reentrantlock do not differ in general, but in very complex synchronization applications, consider using Reentrantlock, especially when you encounter the following 2 requirements.
1. A thread needs to be interrupted while waiting for control of a lock
2. You need to separate some wait-notify,reentrantlock inside the condition application, to control which thread notify
3. With the fair lock function, each incoming thread will be queued

First of all, the Reentrantlock lock mechanism has 2 types, ignoring interrupt lock and response interrupt lock, which gives us a lot of flexibility. For example: If a, B2 thread to compete lock, a thread get lock, b thread wait, but a thread this time really have too many things to deal with, is not return, B thread may be able to wait, want to interrupt themselves, no longer wait for this lock, to deal with other things. This time Reentrantlock provides 2 mechanisms, first, the B thread interrupts itself (or another thread interrupts it), but Reentrantlock does not respond, continue to let the B thread wait, how you interrupt, I am all one ear (synchronized the original language is so) Second, the B thread interrupts itself (or the other thread interrupts it), Reentrantlock handles the interrupt, and no longer waits for the lock to come and completely abandon it. (If you do not understand the Java interrupt mechanism, please refer to the relevant information, and then look back to this article, 80% people do not really understand what is a Java interrupt, hehe)

Here to do a test, first of all a buffer class, it has read operations and write operations, in order not to read dirty data, write and read all need to lock, we first use the Synchronized primitive language to lock, as follows:

public class Buffer {

Private Object lock;

Public Buffer () {
lock = this;
}

public void Write () {
Synchronized (lock) {
Long startTime = System.currenttimemillis ();
System.out.println ("Start writing data to this buff ...");
for (;;) Simulation to be processed for a long time
{
if (System.currenttimemillis ()
-StartTime > Integer.max_value)
Break
}
System.out.println ("finally finished");
}
}

public void Read () {
Synchronized (lock) {
SYSTEM.OUT.PRINTLN ("reading data from this buff");
}
}
}

Next, we define 2 threads, one thread to write, and one thread to read.

public class Writer extends Thread {

Private Buffer buff;

Public Writer (Buffer buff) {
This.buff = buff;
}

@Override
public void Run () {
Buff.write ();
}

}

public class Reader extends Thread {

Private Buffer buff;

Public Reader (Buffer buff) {
This.buff = buff;
}

@Override
public void Run () {

Buff.read ();//It's probably going to be blocked.

SYSTEM.OUT.PRINTLN ("read End");

}

}

Well, write a main to test, we intentionally go to "write", and then let "read" Wait, "write" The time is endless, see "read" can give up.

public class Test {
public static void Main (string[] args) {
Buffer buff = new buffer ();

Final writer writer = new writer (buff);
Final Reader reader = new reader (buff);

Writer.start ();
Reader.start ();

New Thread (New Runnable () {

@Override
public void Run () {
Long start = System.currenttimemillis ();
for (;;) {
Wait 5 seconds to interrupt the read
if (System.currenttimemillis ()
-Start > 5000) {
System.out.println ("Unequal, try to interrupt");
Reader.interrupt ();
Break
}

}

}
}). Start ();

}
}


We look forward to the "read" This thread can exit the waiting lock, but it backfired, once read this thread found that they do not have a lock, it has been waiting, even if it waits to die, also can not get the lock, because the thread to write 2.1 billion seconds to complete t_t, even if we interrupt it, it does not respond, it seems really to die At this time, Reentrantlock gave a mechanism for us to respond to interrupts, so that "reading" can stretch and give up the wait for the lock. Let's rewrite the buffer class, called bufferinterruptibly, which interrupts the cache.

Import Java.util.concurrent.locks.ReentrantLock;

public class Bufferinterruptibly {

Private Reentrantlock lock = new Reentrantlock ();

public void Write () {
Lock.lock ();
try {
Long startTime = System.currenttimemillis ();
System.out.println ("Start writing data to this buff ...");
for (;;) Simulation to be processed for a long time
{
if (System.currenttimemillis ()
-StartTime > Integer.max_value)
Break
}
System.out.println ("finally finished");
} finally {
Lock.unlock ();
}
}

public void Read () throws Interruptedexception {
Lock.lockinterruptibly ();//Note here, you can respond to interrupts
try {
SYSTEM.OUT.PRINTLN ("reading data from this buff");
} finally {
Lock.unlock ();
}
}

}

Of course, to respond to reader and writer changes

public class Reader extends Thread {

Private bufferinterruptibly buff;

Public Reader (bufferinterruptibly buff) {
This.buff = buff;
}

@Override
public void Run () {

try {
Buff.read ()//can receive an interrupt exception, which effectively exits
} catch (Interruptedexception e) {
System.out.println ("I don't read it");
}

SYSTEM.OUT.PRINTLN ("read End");

}

}


public class Writer extends Thread {

Private bufferinterruptibly buff;

Public Writer (bufferinterruptibly buff) {
This.buff = buff;
}

@Override
public void Run () {
Buff.write ();
}

}

public class Test {
public static void Main (string[] args) {
bufferinterruptibly buff = new bufferinterruptibly ();

Final writer writer = new writer (buff);
Final Reader reader = new reader (buff);

Writer.start ();
Reader.start ();

New Thread (New Runnable () {

@Override
public void Run () {
Long start = System.currenttimemillis ();
for (;;) {
if (System.currenttimemillis ()
-Start > 5000) {
System.out.println ("Unequal, try to interrupt");
Reader.interrupt ();
Break
}

}

}
}). Start ();

}
}

This time the "read" thread received a lock.lockinterruptibly () interrupt and effectively handled the "exception".

Using Reentrantlock instead of synchronized keyword primitives in Java concurrency programming

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.