Java multithreading-Lock/Condition,-lockcondition

Source: Internet
Author: User

Java multithreading-Lock/Condition,-lockcondition

In java1.5, Lock objects are used to achieve synchronization, which is more convenient to use.

Use ReentrantLock for synchronization
public class MyService {    private Lock lock = new ReentrantLock();        public void methodA(){        try {            lock.lock();            System.out.println("methodA begin threadName=" + Thread.currentThread().getName()+" time="+System.currentTimeMillis());            Thread.sleep(5000);            System.out.println("methodA end threadName=" + Thread.currentThread().getName()+" time="+System.currentTimeMillis());        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }        public void methodB(){        try {            lock.lock();            System.out.println("methodB begin threadName=" + Thread.currentThread().getName()+" time="+System.currentTimeMillis());            Thread.sleep(5000);            System.out.println("methodB end threadName=" + Thread.currentThread().getName()+" time="+System.currentTimeMillis());        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }}public class Test {    public static void main(String[] args) throws InterruptedException {        MyService service = new MyService();        new Thread(()->service.methodA()).start();        new Thread(()->service.methodA()).start();        new Thread(()->service.methodB()).start();        new Thread(()->service.methodB()).start();    }}
View Code

Test results: the thread that calls lock. lock () holds the "Object monitor". Other threads only compete for the lock when it is released. The effect is the same as that of synchronized.

methodA begin threadName=Thread-0 time=1516242293668methodA end threadName=Thread-0 time=1516242298669methodA begin threadName=Thread-1 time=1516242298669methodA end threadName=Thread-1 time=1516242303671methodB begin threadName=Thread-2 time=1516242303671methodB end threadName=Thread-2 time=1516242308672methodB begin threadName=Thread-3 time=1516242308672methodB end threadName=Thread-3 time=1516242313674
Use Condition to implement wait/notification
Public class MyService {private Lock lock = new ReentrantLock (); private Condition condition = lock. newCondition (); public void await () {try {lock. lock (); System. out. println ("await time is" + System. currentTimeMillis (); condition. await ();} catch (InterruptedException e) {e. printStackTrace ();} finally {lock. unlock () ;}} public void signal () {try {lock. lock (); System. out. println ("signal Time is" + System. currentTimeMillis (); condition. signal ();} finally {lock. unlock () ;}} public class Run {public static void main (String [] args) throws InterruptedException {MyService service = new MyService (); new Thread (() -> service. await ()). start (); Thread. sleep (3000); service. signal ();}}
View Code

Similarity:

1. Call lock. lock () before the conditional await method and signal method. Otherwise, an exception is thrown. Like wait and nofity, run the same command in synchronized code.

2. Object. wait () --> Condition. await (). Object. Policy () --> Condition. signal (), Object. policyall () --> Condition. signalAll ()

Advantages:

Multiple Condition instances can be created in a Lock object, and the thread object can be registered in the specified Condition, so that thread notification can be performed selectively, making scheduling more flexible.

Use multiple Condition to implement partial notification threads
Public class MyService {private Lock lock = new ReentrantLock (); private Condition conditionA = lock. newCondition (); private Condition conditionB = lock. newCondition (); public void awaitA () {try {lock. lock (); System. out. println ("begin awaitA time is" + System. currentTimeMillis () + "Thread name =" + Thread. currentThread (). getName (); conditionA. await (); System. out. println ("end awaitA time is" + System. currentTimeMillis () + "Thread name =" + Thread. currentThread (). getName ();} catch (InterruptedException e) {e. printStackTrace ();} finally {lock. unlock () ;}} public void awaitB () {try {lock. lock (); System. out. println ("begin awaitB time is" + System. currentTimeMillis () + "Thread name =" + Thread. currentThread (). getName (); conditionB. await (); System. out. println ("end awaitB time is" + System. currentTimeMillis () + "Thread name =" + Thread. currentThread (). getName ();} catch (InterruptedException e) {e. printStackTrace ();} finally {lock. unlock () ;}} public void signalAll_A () {try {lock. lock (); System. out. println ("signalAll_ B time is" + System. currentTimeMillis () + "Thread name =" + Thread. currentThread (). getName (); conditionA. signalAll ();} finally {lock. unlock () ;}} public void signalAll_ B () {try {lock. lock (); System. out. println ("signalAll_ B time is" + System. currentTimeMillis () + "Thread name =" + Thread. currentThread (). getName (); conditionB. signalAll ();} finally {lock. unlock () ;}} public class Run {public static void main (String [] args) throws InterruptedException {MyService service = new MyService (); new Thread (() -> service. awaitA ()). start (); new Thread ()-> service. awaitB ()). start (); Thread. sleep (3000); service. signalAll_A ();}}
View Code

Test result: thread B is not awakened.

Begin awaitA time is 1516244219035 Thread name = Thread-0begin awaitB time is 1516244219036 Thread name = Thread-1signalAll_ B time is 1516244222035 Thread name = mainend awaitA time is 1516244222035 Thread name = Thread-0
Producers and consumers
Public class MyList {private Lock lock = new ReentrantLock (); private Condition condition = lock. newCondition (); private volatile List <String> list = new ArrayList <> (10); public void get () {try {System. out. println ("get, listSize =" + list. size (); lock. lock (); while (list. size () = 0) {System. out. println ("get wait, ThreadName =" + Thread. currentThread (). getName (); condition. await ();} System. out. println ("get-1"); list. remove (0); condition. signalAll ();} catch (InterruptedException e) {e. printStackTrace ();} finally {lock. unlock () ;}} public void set () {try {System. out. println ("set, listSize =" + list. size (); lock. lock (); while (list. size () = 10) {System. out. println ("set wait, ThreadName =" + Thread. currentThread (). getName (); condition. await ();} System. out. println ("set + 1"); list. add ("A"); condition. signalAll ();} catch (InterruptedException e) {e. printStackTrace ();} finally {lock. unlock () ;}} public class Run {public static void main (String [] args) throws InterruptedException {MyList consumer = new MyList (); for (int I = 0; I <10; I ++) {new Thread ()-> {while (true) {consumer. set ();}}). start (); new Thread ()-> {while (true) {consumer. get ();}}). start ();}}}
View CodeReentrantReadWriteLock

ReentrantLock has the effect of exclusive, that is, only one thread is executing the task after the ReentrantLock. lock () method at the same time. However, the efficiency is relatively low. Instead, the ReentrantReadWriteLock read/write lock can be used to improve the efficiency. The read/write lock has two locks. One is a read-related lock, also known as a shared lock, and the other is a write-related lock, also known as an exclusive lock. Only read locks are mutually exclusive, and others are mutually exclusive.

Example of non-mutex read locks

Public class Service {private ReentrantReadWriteLock lock = new ReentrantReadWriteLock (); public void read () {try {lock. readLock (). lock (); System. out. println ("Get read lock" + Thread. currentThread (). getName () + "" + System. currentTimeMillis (); Thread. sleep (10000);} catch (InterruptedException e) {e. printStackTrace ();} finally {lock. readLock (). unlock () ;}} public class Run {public static void main (String [] args) throws InterruptedException {Service service Service = new Service (); new Thread (() -> service. read ()). start (); new Thread ()-> service. read ()). start ();}}
View Code

Test results: Read locks are obtained almost simultaneously, indicating they are not mutually exclusive.

Get read lock Thread-0 1516246020468 get read lock Thread-1 1516246020469

Examples of read/write mutex

Public class Service {private ReentrantReadWriteLock lock = new ReentrantReadWriteLock (); public void read () {try {lock. readLock (). lock (); System. out. println ("Get read lock" + Thread. currentThread (). getName () + "" + System. currentTimeMillis (); Thread. sleep (10000);} catch (InterruptedException e) {e. printStackTrace ();} finally {lock. readLock (). unlock () ;}} public void write () {try {lock. writeLock (). lock (); System. out. println ("Get write lock" + Thread. currentThread (). getName () + "" + System. currentTimeMillis (); Thread. sleep (10000);} catch (InterruptedException e) {e. printStackTrace ();} finally {lock. writeLock (). unlock () ;}} public class Run {public static void main (String [] args) throws InterruptedException {Service service Service = new Service (); new Thread (() -> service. read ()). start (); new Thread ()-> service. write ()). start ();}}
View Code

Test results: the write operation can be obtained only after the read lock is released.

Get read lock Thread-0 1516246209130 get write lock Thread-1 1516246219132

 

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.